This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Skip PT_DYNAMIC segment if its p_filesz == 0 [BZ #22101]
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Mon, 25 Sep 2017 17:33:14 -0700
- Subject: [PATCH] Skip PT_DYNAMIC segment if its p_filesz == 0 [BZ #22101]
- Authentication-results: sourceware.org; auth=none
ELF object generated with "objcopy --only-keep-debug" has
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
DYNAMIC 0x0+e28 0x0+200e40 0x0+200e40 0x0+ 0x0+1a0 RW 0x8
with 0 file size. ld.so should skip such PT_DYNAMIC segments.
Tested on x86-64. OK for master?
H.J.
---
[BZ #22101]
* elf/Makefile (tests): Add tst-debug1.
($(objpfx)tst-debug1): New.
($(objpfx)tst-debug1.out): Likewise.
($(objpfx)tst-debug1mod1.so): Likewise.
* elf/dl-load.c (_dl_map_object_from_fd): Skip PT_DYNAMIC segment
if its p_filesz == 0.
* elf/tst-debug1.c: New file.
---
elf/Makefile | 9 ++++++++-
elf/dl-load.c | 7 +++++--
elf/tst-debug1.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 3 deletions(-)
create mode 100644 elf/tst-debug1.c
diff --git a/elf/Makefile b/elf/Makefile
index 7cf959aabd..e21f37e30b 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -181,7 +181,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose
+ tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
+ tst-debug1
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -1417,3 +1418,9 @@ tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
LD_HWCAP_MASK=0x1
tst-env-setuid-tunables-ENV = \
GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
+
+$(objpfx)tst-debug1: $(libdl)
+$(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so
+
+$(objpfx)tst-debug1mod1.so: $(objpfx)testobj1.so
+ $(OBJCOPY) --only-keep-debug $< $@
diff --git a/elf/dl-load.c b/elf/dl-load.c
index a067760cc6..261ec997c8 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1052,8 +1052,11 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
segments are mapped in. We record the addresses it says
verbatim, and later correct for the run-time load address. */
case PT_DYNAMIC:
- l->l_ld = (void *) ph->p_vaddr;
- l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+ if (ph->p_filesz)
+ {
+ l->l_ld = (void *) ph->p_vaddr;
+ l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+ }
break;
case PT_PHDR:
diff --git a/elf/tst-debug1.c b/elf/tst-debug1.c
new file mode 100644
index 0000000000..aa2f4886bf
--- /dev/null
+++ b/elf/tst-debug1.c
@@ -0,0 +1,34 @@
+/* Unit test for dlopen on ELF object from "objcopy --only-keep-debug".
+ Copyright (C) 2017 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+static int
+do_test (void)
+{
+ void *h = dlopen ("tst-debug1mod1.so", RTLD_LAZY);
+ if (h != NULL)
+ {
+ puts ("shouldn't load tst-debug1mod1.so");
+ return 1;
+ }
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.13.5