public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "brnguyen at nvidia dot com" <sourceware-bugzilla@sourceware.org>
To: glibc-bugs@sourceware.org
Subject: [Bug dynamic-link/15271] New: dlmopen()ed shared library with LM_ID_NEWLM crashes if it fails dlsym() twice
Date: Tue, 12 Mar 2013 17:23:00 -0000	[thread overview]
Message-ID: <bug-15271-131@http.sourceware.org/bugzilla/> (raw)

http://sourceware.org/bugzilla/show_bug.cgi?id=15271

             Bug #: 15271
           Summary: dlmopen()ed shared library with LM_ID_NEWLM crashes if
                    it fails dlsym() twice
           Product: glibc
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dynamic-link
        AssignedTo: unassigned@sourceware.org
        ReportedBy: brnguyen@nvidia.com
    Classification: Unclassified


Created attachment 6929
  --> http://sourceware.org/bugzilla/attachment.cgi?id=6929
Test case, and patch which appears to work around the crash

The attached test case loads a dummy DSO using dlmopen() with LM_ID_NEWLM; the
library's constructor, in turn, calls dlsym() with bogus symbol names twice.
This reproduces a segfault in ld-2.15.so on my 64-bit Ubuntu 12.04 LTS system,
kernel 3.2.0-26-generic. I confirmed this also reproduces on an ld.so built
from
git commit 72a3b700c592d39e0e76cd75b2c5ff483e70e083.

Investigating further, it appears that different instances of libc were used
to allocate and free the error string used internally by dlerror(). In my
reproduction using this test case, with the following maps file:

00400000-00401000 r-xp 00000000 08:11 3722707                          
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dlmopen_test
00600000-00601000 r--p 00000000 08:11 3722707                          
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dlmopen_test
00601000-00602000 rw-p 00001000 08:11 3722707                          
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dlmopen_test
555555554000-555555575000 r-xp 00000000 08:11 3728093                  
/home/brnguyen/bin/glibc-build/elf/ld.so
555555774000-555555775000 r--p 00020000 08:11 3728093                  
/home/brnguyen/bin/glibc-build/elf/ld.so
555555775000-555555777000 rw-p 00021000 08:11 3728093                  
/home/brnguyen/bin/glibc-build/elf/ld.so
555555777000-555555798000 rw-p 00000000 00:00 0                         [heap]
7ffff6f8e000-7ffff6f90000 r-xp 00000000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff6f90000-7ffff7190000 ---p 00002000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7190000-7ffff7191000 r--p 00002000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7191000-7ffff7192000 rw-p 00003000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7192000-7ffff7339000 r-xp 00000000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7339000-7ffff7538000 ---p 001a7000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7538000-7ffff753c000 r--p 001a6000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff753c000-7ffff753e000 rw-p 001aa000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff753e000-7ffff7542000 rw-p 00000000 00:00 0
7ffff7542000-7ffff763e000 r-xp 00000000 08:11 3729959                  
/home/brnguyen/bin/glibc-build/lib/libm-2.17.90.so
7ffff763e000-7ffff783e000 ---p 000fc000 08:11 3729959                  
/home/brnguyen/bin/glibc-build/lib/libm-2.17.90.so
7ffff783e000-7ffff783f000 r--p 000fc000 08:11 3729959                  
/home/brnguyen/bin/glibc-build/lib/libm-2.17.90.so
7ffff783f000-7ffff7840000 rw-p 000fd000 08:11 3729959                  
/home/brnguyen/bin/glibc-build/lib/libm-2.17.90.so
7ffff7840000-7ffff7842000 r--p 00000000 08:11 3729060                  
/home/brnguyen/bin/glibc-build/etc/ld.so.cache
7ffff7842000-7ffff7843000 r-xp 00000000 08:11 3722702                  
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dummy.so.1
7ffff7843000-7ffff7a42000 ---p 00001000 08:11 3722702                  
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dummy.so.1
7ffff7a42000-7ffff7a43000 rw-p 00000000 08:11 3722702                  
/home/brnguyen/bugs/1188502/dlmopen_bug_debug/dummy.so.1
7ffff7a43000-7ffff7a46000 rw-p 00000000 00:00 0
7ffff7a46000-7ffff7bed000 r-xp 00000000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7bed000-7ffff7dec000 ---p 001a7000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7dec000-7ffff7df0000 r--p 001a6000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7df0000-7ffff7df2000 rw-p 001aa000 08:11 3416152                  
/home/brnguyen/bin/glibc-build/libc.so
7ffff7df2000-7ffff7df6000 rw-p 00000000 00:00 0
7ffff7df6000-7ffff7df8000 r-xp 00000000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7df8000-7ffff7ff8000 ---p 00002000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7ff8000-7ffff7ff9000 r--p 00002000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7ff9000-7ffff7ffa000 rw-p 00003000 08:11 3730007                  
/home/brnguyen/bin/glibc-build/lib/libdl-2.17.90.so
7ffff7ffa000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffc000-7ffff7ffe000 rw-p 00000000 00:00 0
7ffff7ffe000-7ffff7fff000 r-xp 00000000 00:00 0                         [vdso]
7ffffffdd000-7ffffffff000 rw-p 00000000 00:00 0                         [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                
[vsyscall]

elf/dl-error.c:_dl_signal_error(), which allocates the error string, lives in
ld.so within the application's namespace:

(gdb) p $pc
$22 = (void (*)()) 0x555555562161 <_dl_signal_error+113>
(gdb) p __GI__dl_find_dso_for_object($pc)
$23 = (struct link_map *) 0x5555557759d8
(gdb) p $->l_ns
$25 = 0

But the instance of dlfcn/dlerror.c:_dlerror_run() which clears the error lives
in libdl.so within the dummy library's
new namespace:
(gdb) p $pc
$27 = (void (*)()) 0x7ffff6f8f460 <_dlerror_run>
(gdb) p __GI__dl_find_dso_for_object($pc)
$28 = (struct link_map *) 0x555555778020
(gdb) p $->l_ns
$30 = 1

For some reason, calling dlerror() in between the two dlsym() calls appears to
work around this crash. I attempted to investigate this, but haven't determined
why this suppresses the segfault.

There is an existing helper function in dlerror.c called check_free(), which
first checks if the caller is using the base link map before attempting to free
the error string. In the included patch, I have replaced direct invocations of
free() with check_free() in _dlerror_run() as well as __dlerror(); I verified
this patch fixed the segfault on my system.

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


             reply	other threads:[~2013-03-12 17:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-12 17:23 brnguyen at nvidia dot com [this message]
2013-03-12 20:23 ` [Bug dynamic-link/15271] " carlos at redhat dot com
2013-03-14 23:24 ` brnguyen at nvidia dot com
2013-03-17 17:25 ` carlos at redhat dot com
2013-03-21  0:46 ` brnguyen at nvidia dot com
2013-03-27  4:03 ` carlos at redhat dot com
2013-10-02 22:25 ` neleai at seznam dot cz
2014-06-13 18:42 ` fweimer at redhat dot com
2020-07-23 19:12 ` ajax at redhat dot com
2020-07-23 21:00 ` fweimer at redhat dot com
2020-07-23 21:05 ` fweimer at redhat dot com
2021-04-21 19:42 ` fweimer at redhat dot com
2021-06-09 13:57 ` fweimer at redhat dot com
2021-06-09 15:17 ` fweimer at redhat dot com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-15271-131@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=glibc-bugs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).