Steve Grubb 12e45f
diff -up aide-0.13.1/configure.in.prelink aide-0.13.1/configure.in
Steve Grubb 12e45f
--- aide-0.13.1/configure.in.prelink	2006-12-08 22:49:21.000000000 +0100
Steve Grubb 12e45f
+++ aide-0.13.1/configure.in	2009-05-13 16:14:49.000000000 +0200
Steve Grubb 12e45f
@@ -405,6 +405,30 @@ AS_IF([test "x$with_selinux_support" != 
Steve Grubb 12e45f
 
Steve Grubb 12e45f
 AC_SUBST(SELINUXLIB)
Steve Grubb 12e45f
 
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+AC_MSG_CHECKING(for prelink-support)
Steve Grubb 12e45f
+AC_ARG_WITH([prelink], 
Steve Grubb 12e45f
+            [AC_HELP_STRING([--with-prelink],[use prelink (no checking)])],
Steve Grubb 12e45f
+            [case $with_prelink in 
Steve Grubb 12e45f
+		yes) AC_DEFINE_UNQUOTED(PRELINK_PATH, "/usr/sbin/prelink", [path to prelink])
Steve Grubb 12e45f
+		     AC_DEFINE(WITH_PRELINK,1,[use prelink])
Steve Grubb 12e45f
+		     ELFLIB="-lelf"
Steve Grubb 12e45f
+		     compoptionstring="${compoptionstring}WITH_PRELINK\\n"
Steve Grubb 12e45f
+		     AC_MSG_RESULT([/usr/sbin/prelink])
Steve Grubb 12e45f
+		     ;;
Steve Grubb 12e45f
+		no)  AC_MSG_RESULT(no)
Steve Grubb 12e45f
+		     ;;
Steve Grubb 12e45f
+		*)   AC_DEFINE_UNQUOTED(PRELINK_PATH, "$with_prelink", [path to prelink])
Steve Grubb 12e45f
+		     AC_DEFINE(WITH_PRELINK,1,[use prelink])
Steve Grubb 12e45f
+		     ELFLIB="-lelf"
Steve Grubb 12e45f
+		     compoptionstring="${compoptionstring}WITH_PRELINK\\n"
Steve Grubb 12e45f
+		     AC_MSG_RESULT([$with_prelink])
Steve Grubb 12e45f
+		     ;;
Steve Grubb 12e45f
+	     esac],
Steve Grubb 12e45f
+	    [with_prelink=no]
Steve Grubb 12e45f
+)
Steve Grubb 12e45f
+AC_SUBST(ELFLIB)
Steve Grubb 12e45f
+
Steve Grubb 12e45f
 AC_MSG_CHECKING(for xattr-support)
Steve Grubb 12e45f
 AC_ARG_WITH([xattr],
Steve Grubb 12e45f
 	[AC_HELP_STRING([--with-xattr],
Steve Grubb 12e45f
diff -up aide-0.13.1/src/do_md.c.prelink aide-0.13.1/src/do_md.c
Steve Grubb 12e45f
--- aide-0.13.1/src/do_md.c.prelink	2006-10-27 22:47:20.000000000 +0200
Steve Grubb 12e45f
+++ aide-0.13.1/src/do_md.c	2009-05-13 17:37:51.000000000 +0200
Steve Grubb 12e45f
@@ -65,6 +65,86 @@
Steve Grubb 12e45f
 /*
Steve Grubb 12e45f
 #include <gcrypt.h>
Steve Grubb 12e45f
 */
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
+#include <sys/wait.h>
Steve Grubb 12e45f
+#include <gelf.h>
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+/*
Steve Grubb 12e45f
+ *  Is file descriptor prelinked binary/library?
Steve Grubb 12e45f
+ *  Return: 1(yes) / 0(no)
Steve Grubb 12e45f
+ *  
Steve Grubb 12e45f
+ */
Steve Grubb 12e45f
+int is_prelinked(int fd) {
Steve Grubb 12e45f
+        Elf *elf = NULL;
Steve Grubb 12e45f
+        Elf_Scn *scn = NULL;
Steve Grubb 12e45f
+        Elf_Data *data = NULL;
Steve Grubb 12e45f
+        GElf_Ehdr ehdr;
Steve Grubb 12e45f
+        GElf_Shdr shdr;
Steve Grubb 12e45f
+        GElf_Dyn dyn;
Steve Grubb 12e45f
+        int bingo;
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+        (void) elf_version(EV_CURRENT);
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+        if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL
Steve Grubb 12e45f
+            || elf_kind(elf) != ELF_K_ELF
Steve Grubb 12e45f
+            || gelf_getehdr(elf, &ehdr) == NULL
Steve Grubb 12e45f
+            || !(ehdr.e_type == ET_DYN || ehdr.e_type == ET_EXEC))
Steve Grubb 12e45f
+                return 0;
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+        bingo = 0;
Steve Grubb 12e45f
+        while (!bingo && (scn = elf_nextscn(elf, scn)) != NULL) {
Steve Grubb 12e45f
+                (void) gelf_getshdr(scn, &shdr);
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+                if (shdr.sh_type != SHT_DYNAMIC)
Steve Grubb 12e45f
+                        continue;
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+                while (!bingo && (data = elf_getdata (scn, data)) != NULL) {
Steve Grubb 12e45f
+                        int maxndx = data->d_size / shdr.sh_entsize;
Steve Grubb 12e45f
+                        int ndx;
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+                        for (ndx = 0; ndx < maxndx; ++ndx) {
Steve Grubb 12e45f
+                                (void) gelf_getdyn (data, ndx, &dyn);
Steve Grubb 12e45f
+                                if (!(dyn.d_tag == DT_GNU_PRELINKED || dyn.d_tag == DT_GNU_LIBLIST))
Steve Grubb 12e45f
+                                        continue;
Steve Grubb 12e45f
+                                bingo = 1;
Steve Grubb 12e45f
+                                break;
Steve Grubb 12e45f
+                        }
Steve Grubb 12e45f
+                }
Steve Grubb 12e45f
+        }
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+        return bingo;
Steve Grubb 12e45f
+}
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+/*
Steve Grubb 12e45f
+ * Open path via prelink -y, set fd
Steve Grubb 12e45f
+ * Return: 0(not success) / !0(prelink child process)
Steve Grubb 12e45f
+ *
Steve Grubb 12e45f
+ */
Steve Grubb 12e45f
+pid_t open_prelinked(const char * path, int * fd) {
Steve Grubb 12e45f
+        const char *cmd = PRELINK_PATH;
Steve Grubb 12e45f
+        pid_t pid = 0;
Steve Grubb 12e45f
+        int pipes[2];
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+        pipes[0] = pipes[1] = -1;
Steve Grubb 12e45f
+        pipe(pipes);
Steve Grubb 12e45f
+        if (!(pid = fork())) {
Steve Grubb 12e45f
+                /* child */
Steve Grubb 12e45f
+                close(pipes[0]);
Steve Grubb 12e45f
+                dup2(pipes[1], STDOUT_FILENO);
Steve Grubb 12e45f
+                close(pipes[1]);
Steve Grubb 12e45f
+                unsetenv("MALLOC_CHECK_");
Steve Grubb 12e45f
+                execl(cmd, cmd, "--verify", path, (char *) NULL);
Steve Grubb 12e45f
+        }
Steve Grubb 12e45f
+        /* parent */
Steve Grubb 12e45f
+        close(pipes[1]);
Steve Grubb 12e45f
+        *fd = pipes[0];
Steve Grubb 12e45f
+        return pid;
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+}
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
+
Steve Grubb 12e45f
 void md_init_fail(const char* s,db_line* db,byte** hash,DB_ATTR_TYPE i) {
Steve Grubb 12e45f
   error(0,"Message digest %s initialise failed\nDisabling %s for file %s\n",s,s,db->filename);
Steve Grubb 12e45f
   db->attr=db->attr&(~i);
Steve Grubb 12e45f
@@ -121,6 +201,9 @@ void calc_md(struct AIDE_STAT_TYPE* old_
Steve Grubb 12e45f
   struct AIDE_STAT_TYPE fs;
Steve Grubb 12e45f
   int sres=0;
Steve Grubb 12e45f
   int stat_diff,filedes;
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
+  pid_t pid;
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
 
Steve Grubb 12e45f
   error(255,"calc_md called\n");
Steve Grubb 12e45f
 #ifdef _PARAMETER_CHECK_
Steve Grubb 12e45f
@@ -166,6 +249,22 @@ void calc_md(struct AIDE_STAT_TYPE* old_
Steve Grubb 12e45f
     /*
Steve Grubb 12e45f
       Now we have a 'valid' filehandle to read from a file.
Steve Grubb 12e45f
      */
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
+    /*
Steve Grubb 12e45f
+     * Let's take care of prelinked libraries/binaries 	
Steve Grubb 12e45f
+     */
Steve Grubb 12e45f
+    pid=0;
Steve Grubb 12e45f
+    if ( is_prelinked(filedes) ) {
Steve Grubb 12e45f
+      close(filedes);
Steve Grubb 12e45f
+      pid = open_prelinked(line->filename, &filedes);
Steve Grubb 12e45f
+      if (pid == 0) {
Steve Grubb 12e45f
+        error(0, "Error on starting prelink undo\n");
Steve Grubb 12e45f
+	return;
Steve Grubb 12e45f
+      }
Steve Grubb 12e45f
+    }
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
+
Steve Grubb 12e45f
     off_t r_size=0;
Steve Grubb 12e45f
     off_t size=0;
Steve Grubb 12e45f
     char* buf;
Steve Grubb 12e45f
@@ -176,47 +275,58 @@ void calc_md(struct AIDE_STAT_TYPE* old_
Steve Grubb 12e45f
     
Steve Grubb 12e45f
     if (init_md(&mdc)==RETOK) {
Steve Grubb 12e45f
 #ifdef HAVE_MMAP
Steve Grubb 12e45f
-      off_t curpos=0;
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
+      if (pid == 0) {
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
+        off_t curpos=0;
Steve Grubb 12e45f
 
Steve Grubb 12e45f
-      r_size=fs.st_size;
Steve Grubb 12e45f
-      /* in mmap branch r_size is used as size remaining */
Steve Grubb 12e45f
-      while(r_size>0){
Steve Grubb 12e45f
-	if(r_size
Steve Grubb 12e45f
+        r_size=fs.st_size;
Steve Grubb 12e45f
+        /* in mmap branch r_size is used as size remaining */
Steve Grubb 12e45f
+        while(r_size>0){
Steve Grubb 12e45f
+         if(r_size
Steve Grubb 12e45f
 #ifdef __hpux
Steve Grubb 12e45f
-	  buf = mmap(0,r_size,PROT_READ,MAP_PRIVATE,filedes,curpos);
Steve Grubb 12e45f
+           buf = mmap(0,r_size,PROT_READ,MAP_PRIVATE,filedes,curpos);
Steve Grubb 12e45f
 #else
Steve Grubb 12e45f
-	  buf = mmap(0,r_size,PROT_READ,MAP_SHARED,filedes,curpos);
Steve Grubb 12e45f
+           buf = mmap(0,r_size,PROT_READ,MAP_SHARED,filedes,curpos);
Steve Grubb 12e45f
 #endif
Steve Grubb 12e45f
-	  curpos+=r_size;
Steve Grubb 12e45f
-	  size=r_size;
Steve Grubb 12e45f
-	  r_size=0;
Steve Grubb 12e45f
-	}else {
Steve Grubb 12e45f
+           curpos+=r_size;
Steve Grubb 12e45f
+           size=r_size;
Steve Grubb 12e45f
+           r_size=0;
Steve Grubb 12e45f
+         }else {
Steve Grubb 12e45f
 #ifdef __hpux
Steve Grubb 12e45f
-	  buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_PRIVATE,filedes,curpos);
Steve Grubb 12e45f
+	   buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_PRIVATE,filedes,curpos);
Steve Grubb 12e45f
 #else
Steve Grubb 12e45f
-	  buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_SHARED,filedes,curpos);
Steve Grubb 12e45f
+	   buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_SHARED,filedes,curpos);
Steve Grubb 12e45f
 #endif
Steve Grubb 12e45f
-	  curpos+=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
-	  size=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
-	  r_size-=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
-	}
Steve Grubb 12e45f
-	if ( buf == MAP_FAILED ) {
Steve Grubb 12e45f
-	  error(0,"error mmap'ing %s: %s\n", line->filename,strerror(errno));
Steve Grubb 12e45f
-	  close(filedes);
Steve Grubb 12e45f
-	  close_md(&mdc;;
Steve Grubb 12e45f
-	  return;
Steve Grubb 12e45f
-	}
Steve Grubb 12e45f
-	conf->catch_mmap=1;
Steve Grubb 12e45f
-	if (update_md(&mdc,buf,size)!=RETOK) {
Steve Grubb 12e45f
-	  error(0,"Message digest failed during update\n");
Steve Grubb 12e45f
-	  close_md(&mdc;;
Steve Grubb 12e45f
-	  munmap(buf,size);
Steve Grubb 12e45f
-	  return;
Steve Grubb 12e45f
-	}
Steve Grubb 12e45f
-	munmap(buf,size);
Steve Grubb 12e45f
-	conf->catch_mmap=0;
Steve Grubb 12e45f
+	   curpos+=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
+	   size=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
+	   r_size-=MMAP_BLOCK_SIZE;
Steve Grubb 12e45f
+	 }
Steve Grubb 12e45f
+	 if ( buf == MAP_FAILED ) {
Steve Grubb 12e45f
+	   error(0,"error mmap'ing %s: %s\n", line->filename,strerror(errno));
Steve Grubb 12e45f
+	   close(filedes);
Steve Grubb 12e45f
+	   close_md(&mdc;;
Steve Grubb 12e45f
+	   return;
Steve Grubb 12e45f
+	 }
Steve Grubb 12e45f
+	 conf->catch_mmap=1;
Steve Grubb 12e45f
+	 if (update_md(&mdc,buf,size)!=RETOK) {
Steve Grubb 12e45f
+	   error(0,"Message digest failed during update\n");
Steve Grubb 12e45f
+	   close_md(&mdc;;
Steve Grubb 12e45f
+	   munmap(buf,size);
Steve Grubb 12e45f
+	   return;
Steve Grubb 12e45f
+	 }
Steve Grubb 12e45f
+	 munmap(buf,size);
Steve Grubb 12e45f
+	 conf->catch_mmap=0;
Steve Grubb 12e45f
+        }
Steve Grubb 12e45f
+	/* we have used MMAP, let's return */
Steve Grubb 12e45f
+        close_md(&mdc;;
Steve Grubb 12e45f
+        md2line(&mdc,line);
Steve Grubb 12e45f
+        close(filedes);
Steve Grubb 12e45f
+        return;
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
       }
Steve Grubb 12e45f
-#else /* not HAVE_MMAP */
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
+#endif /* not HAVE_MMAP */
Steve Grubb 12e45f
       buf=malloc(READ_BLOCK_SIZE);
Steve Grubb 12e45f
 #if READ_BLOCK_SIZE>SSIZE_MAX
Steve Grubb 12e45f
 #error "READ_BLOCK_SIZE" is too large. Max value is SSIZE_MAX, and current is READ_BLOCK_SIZE
Steve Grubb 12e45f
@@ -229,11 +339,22 @@ void calc_md(struct AIDE_STAT_TYPE* old_
Steve Grubb 12e45f
 	}
Steve Grubb 12e45f
 	r_size+=size;
Steve Grubb 12e45f
       }
Steve Grubb 12e45f
+
Steve Grubb 12e45f
+#ifdef WITH_PRELINK
Steve Grubb 12e45f
+      if (pid) {
Steve Grubb 12e45f
+        int status;
Steve Grubb 12e45f
+        (void) waitpid(pid, &status, 0);
Steve Grubb 12e45f
+        if (!WIFEXITED(status) || WEXITSTATUS(status)) {
Steve Grubb 12e45f
+          error(0, "Error on exit of prelink child process\n");
Steve Grubb 12e45f
+	  close_md(&mdc;;
Steve Grubb 12e45f
+          return;
Steve Grubb 12e45f
+        }
Steve Grubb 12e45f
+      }
Steve Grubb 12e45f
+#endif
Steve Grubb 12e45f
       free(buf);
Steve Grubb 12e45f
-#endif /* HAVE_MMAP else branch */    
Steve Grubb 12e45f
       close_md(&mdc;;
Steve Grubb 12e45f
       md2line(&mdc,line);
Steve Grubb 12e45f
-      
Steve Grubb 12e45f
+
Steve Grubb 12e45f
     } else {
Steve Grubb 12e45f
       error(3,"Message digest initialization failed.\n");
Steve Grubb 12e45f
       no_hash(line);
Steve Grubb 12e45f
diff -up aide-0.13.1/src/Makefile.am.prelink aide-0.13.1/src/Makefile.am
Steve Grubb 12e45f
--- aide-0.13.1/src/Makefile.am.prelink	2006-10-27 23:10:38.000000000 +0200
Steve Grubb 12e45f
+++ aide-0.13.1/src/Makefile.am	2009-05-13 16:14:49.000000000 +0200
Steve Grubb 12e45f
@@ -50,7 +50,7 @@ aide_SOURCES =	\
Steve Grubb 12e45f
 
Steve Grubb 12e45f
 INCLUDES = -I$(top_srcdir)/include
Steve Grubb 12e45f
 
Steve Grubb 12e45f
-LDADD = -lm @CRYPTLIB@ @ACLLIB@ @SELINUXLIB@ @AUDITLIB@ @ATTRLIB@
Steve Grubb 12e45f
+LDADD = -lm @CRYPTLIB@ @ACLLIB@ @SELINUXLIB@ @AUDITLIB@ @ATTRLIB@ @ELFLIB@
Steve Grubb 12e45f
 
Steve Grubb 12e45f
 AM_LDFLAGS = @LDFLAGS@ @LD_STATIC_FLAG@
Steve Grubb 12e45f