Message ID | 20211210024054.3570891-1-hjl.tools@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [v2] elf: Stop with zero entry point value [BZ #28453] | expand |
Context | Check | Description |
---|---|---|
dj/TryBot-apply_patch | success | Patch applied to master at the time it was sent |
dj/TryBot-32bit | success | Build for i686 |
On 12/10/21 08:10, H.J. Lu via Libc-alpha wrote: > Changes in the v2 patch: > > 1. Use rtld_progname in the error message. > > Stop with zero entry point value unless we are tracing shared objects > since a zero entry point value in the ELF header indicates there is no > associated entry point. Now we get > > $ ./elf/ld.so /lib64/libstdc++.so.6.0.29 > ./elf/ld.so: cannot execute '/lib64/libstdc++.so.6.0.29' without entry point > $ > > instead of > > $ /lib64/ld-linux-x86-64.so.2 /lib64/libstdc++.so.6.0.29 > Segmentation fault (core dumped) > $ > > This fixes [BZ #28453]. The change that introduced the zero entry point in binutils: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=5226a6a892f922ea672e5775c61776830aaf27b7 and original context of the discussion: https://bugzilla.redhat.com/show_bug.cgi?id=2004952 LGTM. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org> > --- > elf/Makefile | 10 ++++++++++ > elf/rtld.c | 8 ++++++++ > elf/tst-rtld-run-dso.sh | 33 +++++++++++++++++++++++++++++++++ > 3 files changed, 51 insertions(+) > create mode 100755 elf/tst-rtld-run-dso.sh > > diff --git a/elf/Makefile b/elf/Makefile > index ef36008673..1832dfa537 100644 > --- a/elf/Makefile > +++ b/elf/Makefile > @@ -50,6 +50,10 @@ ifeq (yesyes,$(build-shared)$(run-built-tests)) > tests-special += $(objpfx)list-tunables.out > endif > > +ifeq (yes,$(build-shared)) > +tests-special += $(objpfx)tst-rtld-run-dso.out > +endif > + > # Make sure that the compiler does not insert any library calls in tunables > # code paths. > ifeq (yes,$(have-loop-to-function)) > @@ -1877,6 +1881,12 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so > $(objpfx)/tst-rtld-list-tunables.out > $@; \ > $(evaluate-test) > > +$(objpfx)tst-rtld-run-dso.out: tst-rtld-run-dso.sh $(objpfx)ld.so \ > + $(objpfx)testobj1.so > + $(SHELL) tst-rtld-run-dso.sh $(objpfx)ld.so $(objpfx)testobj1.so \ > + '$(test-wrapper-env)' '$(run_program_env)' > $@ > + $(evaluate-test) > + > tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN' Test. OK. > > $(objpfx)tst-rtld-help.out: $(objpfx)ld.so > diff --git a/elf/rtld.c b/elf/rtld.c > index 6ce1e07dc0..b4373ba193 100644 > --- a/elf/rtld.c > +++ b/elf/rtld.c > @@ -1424,6 +1424,14 @@ dl_main (const ElfW(Phdr) *phdr, > implementations which has no real free() function it does not > makes sense to free the old string first. */ > main_map->l_name = (char *) ""; > + > + /* Stop if there is no associated entry point and we are not > + tracing shared objects. */ > + if (main_map->l_entry == main_map->l_addr > + && state.mode != rtld_mode_trace) > + _dl_fatal_printf("%s: cannot execute '%s' without entry point\n", > + ld_so_name, rtld_progname); > + Bail out if the entry point is same as load address. OK. > *user_entry = main_map->l_entry; > > /* Set bit indicating this is the main program map. */ > diff --git a/elf/tst-rtld-run-dso.sh b/elf/tst-rtld-run-dso.sh > new file mode 100755 > index 0000000000..5192f64210 > --- /dev/null > +++ b/elf/tst-rtld-run-dso.sh > @@ -0,0 +1,33 @@ > +#!/bin/sh > +# Test for ld.so on a shared library with no associated entry point. > +# Copyright (C) 2021 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 > +# <https://www.gnu.org/licenses/>. > + > +set -e > + > +rtld=$1 > +dso=$2 > +test_wrapper_env=$3 > +run_program_env=$4 > + > +LC_ALL=C > +export LC_ALL > + > +${test_wrapper_env} \ > +${run_program_env} \ > +$rtld $dso 2>&1 \ > +| grep "cannot execute" > OK. Thanks, Siddhesh
diff --git a/elf/Makefile b/elf/Makefile index ef36008673..1832dfa537 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -50,6 +50,10 @@ ifeq (yesyes,$(build-shared)$(run-built-tests)) tests-special += $(objpfx)list-tunables.out endif +ifeq (yes,$(build-shared)) +tests-special += $(objpfx)tst-rtld-run-dso.out +endif + # Make sure that the compiler does not insert any library calls in tunables # code paths. ifeq (yes,$(have-loop-to-function)) @@ -1877,6 +1881,12 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so $(objpfx)/tst-rtld-list-tunables.out > $@; \ $(evaluate-test) +$(objpfx)tst-rtld-run-dso.out: tst-rtld-run-dso.sh $(objpfx)ld.so \ + $(objpfx)testobj1.so + $(SHELL) tst-rtld-run-dso.sh $(objpfx)ld.so $(objpfx)testobj1.so \ + '$(test-wrapper-env)' '$(run_program_env)' > $@ + $(evaluate-test) + tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN' $(objpfx)tst-rtld-help.out: $(objpfx)ld.so diff --git a/elf/rtld.c b/elf/rtld.c index 6ce1e07dc0..b4373ba193 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1424,6 +1424,14 @@ dl_main (const ElfW(Phdr) *phdr, implementations which has no real free() function it does not makes sense to free the old string first. */ main_map->l_name = (char *) ""; + + /* Stop if there is no associated entry point and we are not + tracing shared objects. */ + if (main_map->l_entry == main_map->l_addr + && state.mode != rtld_mode_trace) + _dl_fatal_printf("%s: cannot execute '%s' without entry point\n", + ld_so_name, rtld_progname); + *user_entry = main_map->l_entry; /* Set bit indicating this is the main program map. */ diff --git a/elf/tst-rtld-run-dso.sh b/elf/tst-rtld-run-dso.sh new file mode 100755 index 0000000000..5192f64210 --- /dev/null +++ b/elf/tst-rtld-run-dso.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# Test for ld.so on a shared library with no associated entry point. +# Copyright (C) 2021 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 +# <https://www.gnu.org/licenses/>. + +set -e + +rtld=$1 +dso=$2 +test_wrapper_env=$3 +run_program_env=$4 + +LC_ALL=C +export LC_ALL + +${test_wrapper_env} \ +${run_program_env} \ +$rtld $dso 2>&1 \ +| grep "cannot execute"