elf: Fix pldd (BZ#18035)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 11 Apr 2019 21:12:00 +0000 (18:12 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 23 Apr 2019 21:13:08 +0000 (18:13 -0300)
commit1a4c27355e146b6d8cc6487b998462c7fdd1048f
treef4e0729fa653ce0724858156b63e53ab7a1b87e6
parent2d398aa272648a6078b56899db84f86f7b3bdf39
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.
ChangeLog
elf/Makefile
elf/pldd-xx.c
elf/pldd.c
elf/tst-pldd.c [new file with mode: 0644]