From patchwork Wed Nov 7 12:32:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Newall X-Patchwork-Id: 30060 Received: (qmail 27726 invoked by alias); 7 Nov 2018 12:32:20 -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 27716 invoked by uid 89); 7 Nov 2018 12:32:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT autolearn=ham version=3.3.2 spammy=favour, know X-HELO: hawking.rebel.net.au Subject: Re: [PATCH] ld.so: command argument "--preload" To: Florian Weimer Cc: Carlos O'Donell , libc-alpha@sourceware.org References: <322fb70a-9c0e-100b-4366-dfa7e5134aa5@davidnewall.com> <265bec63-9875-7268-2199-c7e133b2298e@davidnewall.com> <874ldb7gxp.fsf@oldenburg.str.redhat.com> <5f79f366-d687-583f-940c-36c169bd34a9@davidnewall.com> <87sh0eqssf.fsf@oldenburg.str.redhat.com> <8816b7fc-d798-42ee-de51-d1de56e6887c@davidnewall.com> <87zhuljiev.fsf@oldenburg.str.redhat.com> From: David Newall Message-ID: <43265e8e-956a-f895-6c04-8cd6898a8c97@davidnewall.com> Date: Wed, 7 Nov 2018 23:02:09 +1030 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 Mime-Version: 1.0 In-Reply-To: <87zhuljiev.fsf@oldenburg.str.redhat.com> On 7/11/18 8:53 pm, Florian Weimer wrote: > Yes, as long as it's not text/html. Please resend your patch as an > attachment; it looks like some lines were wrapped. I like HTML email (I know! and I've been doing UNIX since '80s) but this client is doing the movement no favour by mangling what I asked to be pre-formatted text.  Here it is as an attachment. diff --git a/elf/Makefile b/elf/Makefile index d72e7b6..901e188 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -353,7 +353,8 @@ endif ifeq (yes,$(build-shared)) ifeq ($(run-built-tests),yes) -tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out +tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \ + $(objpfx)tst-rtld-preload.out endif tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \ $(objpfx)check-localplt.out $(objpfx)check-initfini.out @@ -882,6 +883,13 @@ $(objpfx)tst-rtld-load-self.out: tst-rtld-load-self.sh $(objpfx)ld.so $(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' > $@; \ $(evaluate-test) +tst-rtld-preload-OBJS = $(subst $(empty) ,:,$(strip $(preloadtest-preloads:=.so))) +$(objpfx)tst-rtld-preload.out: tst-rtld-preload.sh $(objpfx)ld.so \ + $(objpfx)preloadtest + $(SHELL) $^ '$(test-wrapper)' '$(test-wrapper-env)' '$(run_program_env)' \ + '$(rpath-link)' '$(tst-rtld-preload-OBJS)' > $@; \ + $(evaluate-test) + $(objpfx)initfirst: $(libdl) $(objpfx)initfirst.out: $(objpfx)firstobj.so diff --git a/elf/rtld.c b/elf/rtld.c index 1b0c747..f046f6e 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -826,6 +826,8 @@ static const char *library_path attribute_relro; 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 @@ -833,8 +835,9 @@ static int version_info attribute_relro; (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; @@ -858,7 +861,7 @@ handle_ld_preload (const char *preloadlist, struct link_map *main_map) ++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; } @@ -978,6 +981,13 @@ dl_main (const ElfW(Phdr) *phdr, _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; @@ -1006,7 +1016,8 @@ of this helper program; chances are you did not intend to run this program.\n\ 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; @@ -1620,7 +1631,16 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", 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); diff --git a/elf/tst-rtld-preload.sh b/elf/tst-rtld-preload.sh new file mode 100755 index 0000000..4a6a58d --- /dev/null +++ b/elf/tst-rtld-preload.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Test how rtld loads itself. +# Copyright (C) 2012-2016 Free Software Foundation, Inc. +# This file is part of the GNU C Library. +# + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# . + +set -e + +rtld=$1 +test_program=$2 +test_wrapper=$3 +test_wrapper_env=$4 +run_program_env=$5 +library_path=$6 +preload=$7 + +echo "# [${test_wrapper}] [$rtld] [--library-path] [$library_path] [--preload] [$preload] [$test_program]" +${test_wrapper_env} \ +${run_program_env} \ +${test_wrapper} $rtld --library-path $library_path --preload $preload $test_program 2>&1 && rc=0 || rc=$? +echo "# exit status $rc" + +exit $rc