[Bug dynamic-link/18035] New: pldd does no longer work, enters infinite loop

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] New: pldd does no longer work, enters infinite loop

agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

            Bug ID: 18035
           Summary: pldd does no longer work, enters infinite loop
           Product: glibc
           Version: 2.20
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dynamic-link
          Assignee: unassigned at sourceware dot org
          Reporter: fweimer at redhat dot com
             Flags: security-

This just hangs:

$ pldd $$
17928:    /usr/bin/bash

It loops around in pldd-xx.c, here (line numbers are from glibc 2.20 in Fedora
21):

201        again:
202          while (1)
203        {
204          ssize_t n = pread64 (memfd, str, strsize, name_offset);
205          if (n == -1)
206            {
207              error (0, 0, gettext ("cannot read object name"));
208              return EXIT_FAILURE;
209            }
210    
211          if (memchr (str, '\0', n) != NULL)
212            break;
213    
214          str = extend_alloca (str, strsize, strsize * 2);
215        }
216    
217          if (str[0] == '\0' && name_offset == m.l_name
218          && m.l_libname != 0)
219        {
220          /* Try the l_libname element.  */
221          struct E(libname_list) ln;
222          if (pread64 (memfd, &ln, sizeof (ln), m.l_libname) == sizeof (ln))
223            {
224              name_offset = ln.name;
225              goto again;
226            }
227        }

(I see a similar issue in master.)

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Andreas Schwab <[hidden email]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|2.20                        |2.19

--- Comment #1 from Andreas Schwab <[hidden email]> ---
Already broken in 2.19.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Michael Kerrisk <mtk.manpages at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mtk.manpages at gmail dot com

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Yaakov Selkowitz <yselkowi at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yselkowi at redhat dot com

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Carlos O'Donell <carlos at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |carlos at redhat dot com

--- Comment #2 from Carlos O'Donell <carlos at redhat dot com> ---
I see no reason for keeping pldd.

This does exactly the same:

cat >> pldd.sh <<EOF
#!/bin/sh
gdb -ex "set confirm off" -ex "set height 0" -ex "info shared" -ex "quit" -p $1
| grep '^0x.*0x'
EOF

If we had a dynamic linker library we could use to reuse all of the code that
goes into loading a shared library, then that would be fine.

As it stands today, pldd just isn't that useful. The fact that it's broken
since 2.19 and nobody complained shows it's not used.

I would suggest we remove pldd rather than fixing whatever assumption it has
that's wrong.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #3 from Yaakov Selkowitz <yselkowi at redhat dot com> ---
Is https://lkml.org/lkml/2013/7/23/163 related?

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #4 from Florian Weimer <fweimer at redhat dot com> ---
(In reply to Yaakov Selkowitz from comment #3)
> Is https://lkml.org/lkml/2013/7/23/163 related?

I don't think so.  The process attach is successful in the hangs I see (ptrace
(PTRACE_ATTACH) returns 0), it really loops around pread64.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

richard at wetafx dot co.nz <richard at wetafx dot co.nz> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |richard at wetafx dot co.nz

--- Comment #5 from richard at wetafx dot co.nz <richard at wetafx dot co.nz> ---
What is the current intention for addressing this bug request?

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #6 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Adhemerval Zanella
<[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=1a4c27355e146b6d8cc6487b998462c7fdd1048f

commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f
Author: Adhemerval Zanella <[hidden email]>
Date:   Thu Apr 11 18:12:00 2019 -0300

    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.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Adhemerval Zanella <adhemerval.zanella at linaro dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |adhemerval.zanella at linaro dot o
                   |                            |rg
         Resolution|---                         |FIXED
           Assignee|unassigned at sourceware dot org   |adhemerval.zanella at linaro dot o
                   |                            |rg
   Target Milestone|---                         |2.30

--- Comment #7 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
Fixed on 2.30 (commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f).

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://bugzilla.redhat.com
                   |                            |/show_bug.cgi?id=1702539

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://bugzilla.redhat.com
                   |                            |/show_bug.cgi?id=1361689

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #8 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The release/2.29/master branch has been updated by Florian Weimer
<[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=eaea1dfbe95a31c29adc259100569962cddb6f19

commit eaea1dfbe95a31c29adc259100569962cddb6f19
Author: Adhemerval Zanella <[hidden email]>
Date:   Fri Apr 26 13:58:31 2019 +0200

    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.

    (cherry picked from commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f)

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #9 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The release/2.28/master branch has been updated by Florian Weimer
<[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5cbb73004b635e762e20b447c2d93c307cb40f41

commit 5cbb73004b635e762e20b447c2d93c307cb40f41
Author: Adhemerval Zanella <[hidden email]>
Date:   Fri Apr 26 14:08:20 2019 +0200

    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.

    (cherry picked from commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f)
    (Backported without the test case due to lack of test-in-container
    support.)

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug dynamic-link/18035] pldd does no longer work, enters infinite loop

agner at agner dot org
In reply to this post by agner at agner dot org
https://sourceware.org/bugzilla/show_bug.cgi?id=18035

--- Comment #10 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The release/2.27/master branch has been updated by Florian Weimer
<[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=1961e5c72965a428e5ff18a49c4efdcb65991347

commit 1961e5c72965a428e5ff18a49c4efdcb65991347
Author: Adhemerval Zanella <[hidden email]>
Date:   Fri Apr 26 14:06:31 2019 +0200

    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.

    (cherry picked from commit 1a4c27355e146b6d8cc6487b998462c7fdd1048f)
    (Backported without the test case due to lack of test-in-container
    support.)

--
You are receiving this mail because:
You are on the CC list for the bug.