about summary refs log tree commit diff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-09-26 13:49:48 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-09-26 13:50:01 -0700
commit592d5c75392e1da170050a4999af0618c4865aed (patch)
treea0f9b248f75e6be63bf3aa9794e37b01ad6398c4 /elf/dl-load.c
parent2d9193f2f55767c71333d425e140e22c3e15dc3d (diff)
downloadglibc-592d5c75392e1da170050a4999af0618c4865aed.tar.gz
glibc-592d5c75392e1da170050a4999af0618c4865aed.tar.xz
glibc-592d5c75392e1da170050a4999af0618c4865aed.zip
Skip PT_DYNAMIC segment with p_filesz == 0 [BZ #22101]
ELF objects generated with "objcopy --only-keep-debug" have

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.

Without a PT_DYNAMIC segment the loading of the shared object will
fail, and therefore ldd on such objects will also fail instead of
crashing. This provides better diagnostics for tooling that is
attempting to inspect the invalid shared objects which may just
contain debug information.

	[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
	with p_filesz == 0.
	* elf/tst-debug1.c: New file.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index a067760cc6..1220183ce2 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1052,8 +1052,14 @@ _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)
+	    {
+	      /* Debuginfo only files from "objcopy --only-keep-debug"
+		 contain a PT_DYNAMIC segment with p_filesz == 0.  Skip
+		 such a segment to avoid a crash later.  */
+	      l->l_ld = (void *) ph->p_vaddr;
+	      l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+	    }
 	  break;
 
 	case PT_PHDR: