Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Oct 2001 01:15:44 -0800 (PST)
From:      Lamont Granquist <lamont@scriptkiddie.org>
To:        <hackers@freebsd.org>
Cc:        <jdp@polstra.com>
Subject:   Re: /etc/ld.so.preload?
Message-ID:  <20011031010149.C24547-200000@coredump.scriptkiddie.org>
In-Reply-To: <20011030230606.A35139-200000@coredump.scriptkiddie.org>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]

Sorry, that one isn't backwards compatible with the present version of
the hints file.  This one behaves nicer.

On Tue, 30 Oct 2001, Lamont Granquist wrote:
> Well, here's a short patch to add the necessarily functionality to
> /var/run/ld-elf.so.hints and /usr/libexec/ld-elf.so.1.  If this is
> acceptable, /sbin/ldconfig would need to be patched.
>
> Looks like the major bug is that if you preload libraries globally you
> break linux binary compatibility.
>
> On Tue, 30 Oct 2001, Lamont Granquist wrote:
> > Is there anything in FreeBSD that gives this functionality?  My reading of
> > src/libexec/rtld-elf/rtld.c in both -stable and -current seems to indicate
> > that there isn't any such functionality (i need the global functionality
> > that LD_PRELOAD doesn't give me).  I'd be willing to write a patch for it,
> > but I'd need some guidance on what would be a proper way to fix it.
> >
> > I'm thinking of a patch to ldconfig to get /etc/ld.so.preload into the
> > hints file and then to hack gethints() in rtld.c to take an argument
> > indicating which path you want to return.
> >
> >
> >
> > To Unsubscribe: send mail to majordomo@FreeBSD.org
> > with "unsubscribe freebsd-hackers" in the body of the message
> >
> >
>

[-- Attachment #2 --]
--- include/elf-hints.h~	Tue Oct 30 18:29:57 2001
+++ include/elf-hints.h	Tue Oct 30 18:31:47 2001
@@ -40,7 +40,10 @@
 	u_int32_t	dirlist;	/* Offset of directory list in
 					   string table */
 	u_int32_t	dirlistlen;	/* strlen(dirlist) */
-	u_int32_t	spare[26];	/* Room for expansion */
+	u_int32_t	preloadlist;	/* Offset of preload list in 
+					   string table */
+	u_int32_t	preloadlistlen; /* strlen(preloadlist) */
+	u_int32_t	spare[24];	/* Room for expansion */
 };
 
 #define ELFHINTS_MAGIC	0x746e6845
--- libexec/rtld-elf/rtld.c~	Tue Oct 30 18:28:00 2001
+++ libexec/rtld-elf/rtld.c	Wed Oct 31 00:55:05 2001
@@ -52,8 +52,10 @@
 #include "debug.h"
 #include "rtld.h"
 
-#define END_SYM		"_end"
-#define PATH_RTLD	"/usr/libexec/ld-elf.so.1"
+#define END_SYM			"_end"
+#define PATH_RTLD		"/usr/libexec/ld-elf.so.1"
+#define HINT_LIBRARY_PATH	0x01
+#define HINT_PRELOAD		0x02
 
 /* Types. */
 typedef void (*func_ptr_type)();
@@ -80,7 +82,7 @@
 static void errmsg_restore(char *);
 static char *errmsg_save(void);
 static char *find_library(const char *, const Obj_Entry *);
-static const char *gethints(void);
+static char *gethints(int);
 static void init_dag(Obj_Entry *);
 static void init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *);
 static void init_rtld(caddr_t);
@@ -91,7 +93,7 @@
 static void linkmap_add(Obj_Entry *);
 static void linkmap_delete(Obj_Entry *);
 static int load_needed_objects(Obj_Entry *);
-static int load_preload_objects(void);
+static int load_preload_objects(char *);
 static Obj_Entry *load_object(char *);
 static void lock_check(void);
 static Obj_Entry *obj_from_addr(const void *);
@@ -359,7 +361,9 @@
     sym_zero.st_shndx = SHN_ABS;
 
     dbg("loading LD_PRELOAD libraries");
-    if (load_preload_objects() == -1)
+    if (load_preload_objects(ld_preload) == -1)
+	die();
+    if (load_preload_objects(gethints(HINT_PRELOAD)) == -1)
 	die();
     preload_tail = obj_tail;
 
@@ -805,7 +809,7 @@
     if ((refobj != NULL &&
       (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
       (pathname = search_library_path(name, ld_library_path)) != NULL ||
-      (pathname = search_library_path(name, gethints())) != NULL ||
+      (pathname = search_library_path(name, gethints(HINT_LIBRARY_PATH))) != NULL ||
       (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
 	return pathname;
 
@@ -873,38 +877,54 @@
  * necessary.  Returns NULL if there are problems with the hints file,
  * or if the search path there is empty.
  */
-static const char *
-gethints(void)
+static char *
+gethints(int hintflag)
 {
-    static char *hints;
+    static char *preload;
+    static char *library_path;
 
-    if (hints == NULL) {
+    if ((library_path == NULL) || (preload == NULL)) {
 	int fd;
 	struct elfhints_hdr hdr;
 	char *p;
 
 	/* Keep from trying again in case the hints file is bad. */
-	hints = "";
+	library_path = "";
+	preload = "";
 
 	if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
 	    return NULL;
 	if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
 	  hdr.magic != ELFHINTS_MAGIC ||
 	  hdr.version != 1) {
-	    close(fd);
-	    return NULL;
+	    goto cleanup;
 	}
 	p = xmalloc(hdr.dirlistlen + 1);
 	if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
 	  read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) {
 	    free(p);
-	    close(fd);
-	    return NULL;
+	    goto cleanup;
 	}
-	hints = p;
+	library_path = p;
+	p = xmalloc(hdr.preloadlistlen + 1);
+	if (hdr.preloadlistlen == 0 ||
+	  lseek(fd, hdr.strtab + hdr.preloadlist, SEEK_SET) == -1 ||
+	  read(fd, p, hdr.preloadlistlen + 1) != hdr.preloadlistlen + 1) {
+	    free(p);
+	    goto cleanup;
+	}
+	preload = p;
+cleanup:
 	close(fd);
     }
-    return hints[0] != '\0' ? hints : NULL;
+    switch (hintflag) {
+	case HINT_LIBRARY_PATH:
+          return library_path[0] != '\0' ? library_path : NULL;
+	case HINT_PRELOAD:
+          return preload[0] != '\0' ? preload : NULL;
+	default:
+	  return NULL;
+    }
 }
 
 static void
@@ -1077,9 +1097,8 @@
 }
 
 static int
-load_preload_objects(void)
+load_preload_objects(char *p)
 {
-    char *p = ld_preload;
     static const char delim[] = " \t:;";
 
     if (p == NULL)

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011031010149.C24547-200000>