about summary refs log tree commit diff
path: root/elf/Makefile
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-04-11 18:12:00 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-04-23 18:13:08 -0300
commit1a4c27355e146b6d8cc6487b998462c7fdd1048f (patch)
treef4e0729fa653ce0724858156b63e53ab7a1b87e6 /elf/Makefile
parent2d398aa272648a6078b56899db84f86f7b3bdf39 (diff)
downloadglibc-1a4c27355e146b6d8cc6487b998462c7fdd1048f.tar.gz
glibc-1a4c27355e146b6d8cc6487b998462c7fdd1048f.tar.xz
glibc-1a4c27355e146b6d8cc6487b998462c7fdd1048f.zip
elf: Fix pldd (BZ#18035)
Since 9182aa67994 (Fix vDSO l_name for GDB's, BZ#387) the initial link_map
for executable itself and loader will have both l_name and l_libname->name
holding the same value due:

 elf/dl-object.c

 95   new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1;

Since newname->name points to new->l_libname->name.

This leads to pldd to an infinite call at:

 elf/pldd-xx.c

203     again:
204       while (1)
205         {
206           ssize_t n = pread64 (memfd, tmpbuf.data, tmpbuf.length, name_offset);

228           /* Try the l_libname element.  */
229           struct E(libname_list) ln;
230           if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
231             {
232               name_offset = ln.name;
233               goto again;
234             }

Since the value at ln.name (l_libname->name) will be the same as previously
read. The straightforward fix is just avoid the check and read the new list
entry.

I checked also against binaries issues with old loaders with fix for BZ#387,
and pldd could dump the shared objects.

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, and
powerpc64le-linux-gnu.

	[BZ #18035]
	* elf/Makefile (tests-container): Add tst-pldd.
	* elf/pldd-xx.c: Use _Static_assert in of pldd_assert.
	(E(find_maps)): Avoid use alloca, use default read file operations
	instead of explicit LFS names, and fix infinite	loop.
	* elf/pldd.c: Explicit set _FILE_OFFSET_BITS, cleanup headers.
	(get_process_info): Use _Static_assert instead of assert, use default
	directory operations instead of explicit LFS names, and free some
	leadek pointers.
	* elf/tst-pldd.c: New file.
Diffstat (limited to 'elf/Makefile')
-rw-r--r--elf/Makefile1
1 files changed, 1 insertions, 0 deletions
diff --git a/elf/Makefile b/elf/Makefile
index 310a37cc13..0b4a877880 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -194,6 +194,7 @@ tests-internal += loadtest unload unload2 circleload1 \
 	 tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
 	 tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
 	 tst-create_format1
+tests-container += tst-pldd
 ifeq ($(build-hardcoded-path-in-tests),yes)
 tests += tst-dlopen-aout
 tst-dlopen-aout-no-pie = yes