This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] ld.so: command argument "--preload"
Hello all,
I'm new here, so I'm probably doing this wrong. Please tell me what I
should be doing.
CHANGE
Add a --preload command argument to ld.so (aka rtld.c)
RATIONALE
I worked around a deficiency in a 3rd party binary, via LD_PRELOAD,
however any sub-process invoked by that binary tried (as advertised) to
load the library, too. When I needed to run the (32-bit) binary under a
64-bit OS, I found that the sub-processes worked, but elicited an ugly
error about wrong ELF class. What I needed was a way of preloading a
library for only the binary that I was executing, and not for any
sub-process (e.g. executed via system(3)).
I feel that a --preload argument is a minor change on top of which the
LD_PRELOAD environment variable should be built. That is, there should
be a way to preload a library without it propagating to all sub-processes.
Here is my patch.
---8<------8<------8<------8<------8<------8<------8<------8<------8<------8<------8<------8<---
--- elf/rtld.c.orig 2018-08-22 22:14:20.584489324 +0930
+++ elf/rtld.c 2018-08-22 22:17:22.151716644 +0930
@@ -745,6 +745,8 @@
static const char *preloadlist attribute_relro;
/* Nonzero if information about versions has to be printed. */
static int version_info attribute_relro;
+/* The preload list passed as a command argument. */
+static const char *preloadarg attribute_relro;
/* The LD_PRELOAD environment variable gives list of libraries
separated by white space or colons that are loaded before the
@@ -752,8 +754,9 @@
(If the binary is running setuid all elements containing a '/' are
ignored since it is insecure.) Return the number of preloads
performed. */
+/* Ditto for --preload command argument */
unsigned int
-handle_ld_preload (const char *preloadlist, struct link_map *main_map)
+handle_preload_list (const char *preloadlist, struct link_map *main_map, const char *where)
{
unsigned int npreloads = 0;
const char *p = preloadlist;
@@ -777,7 +780,7 @@
++p;
if (dso_name_valid_for_suid (fname))
- npreloads += do_preload (fname, main_map, "LD_PRELOAD");
+ npreloads += do_preload (fname, main_map, where);
}
return npreloads;
}
@@ -902,6 +905,13 @@
_dl_argc -= 2;
_dl_argv += 2;
}
+ else if (! strcmp(_dl_argv[1], "--preload") && _dl_argc > 2)
+ {
+ preloadarg = _dl_argv[2];
+ _dl_skip_args += 2;
+ _dl_argc -= 2;
+ _dl_argv += 2;
+ }
else
break;
@@ -930,7 +940,8 @@
variable LD_LIBRARY_PATH\n\
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
in LIST\n\
- --audit LIST use objects named in LIST as auditors\n");
+ --audit LIST use objects named in LIST as auditors\n\
+ --preload LIST preload objects named in LIST\n");
++_dl_skip_args;
--_dl_argc;
@@ -1536,7 +1547,16 @@
if (__glibc_unlikely (preloadlist != NULL))
{
HP_TIMING_NOW (start);
- npreloads += handle_ld_preload (preloadlist, main_map);
+ npreloads += handle_preload_list (preloadlist, main_map, "LD_PRELOAD");
+ HP_TIMING_NOW (stop);
+ HP_TIMING_DIFF (diff, start, stop);
+ HP_TIMING_ACCUM_NT (load_time, diff);
+ }
+
+ if (__glibc_unlikely (preloadarg != NULL))
+ {
+ HP_TIMING_NOW (start);
+ npreloads += handle_preload_list (preloadarg, main_map, "--preload");
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (diff, start, stop);
HP_TIMING_ACCUM_NT (load_time, diff);