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>
