From patchwork Wed Oct 10 07:52:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Newall X-Patchwork-Id: 29690 Received: (qmail 41454 invoked by alias); 10 Oct 2018 07:52:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 41418 invoked by uid 89); 10 Oct 2018 07:52:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=white, CHANGE, ugly, auditors X-HELO: hawking.rebel.net.au Subject: Re: [PATCH] ld.so: command argument "--preload" References: <265bec63-9875-7268-2199-c7e133b2298e@davidnewall.com> To: libc-alpha@sourceware.org From: David Newall X-Forwarded-Message-Id: <265bec63-9875-7268-2199-c7e133b2298e@davidnewall.com> Message-ID: Date: Wed, 10 Oct 2018 18:22:43 +1030 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <265bec63-9875-7268-2199-c7e133b2298e@davidnewall.com> Ping! (Copyright assignment now complete.) -------- Forwarded Message -------- Subject: [PATCH] ld.so: command argument "--preload" Date: Sat, 1 Sep 2018 00:16:30 +0930 From: David Newall To: libc-alpha@sourceware.org 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);