This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/24595] New: [2.28 Regression]: Deadlock in atfork handler which calls dlclose


https://sourceware.org/bugzilla/show_bug.cgi?id=24595

            Bug ID: 24595
           Summary: [2.28 Regression]: Deadlock in atfork handler which
                    calls dlclose
           Product: glibc
           Version: 2.28
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: nptl
          Assignee: unassigned at sourceware dot org
          Reporter: gentoo-bugzilla at jdrake dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

https://bugs.gentoo.org/685024

The specific use case is kind of complicated.  I am using OpenVPN with a pkcs11
"smartcard" (actually GnuK).  The software stack involved at the time consists
of

sys-libs/glibc-2.28-r6
sys-apps/pcsc-lite-1.8.24
dev-libs/opensc-0.18.0
dev-libs/pkcs11-helper-1.25.1
net-vpn/openvpn-2.4.6

Note that both glibc and opensc have newer versions now, but I have not gotten
the chance to test with those.

The situation is that pkcs11-helper installs an atfork handler, whose purpose
is to deinitialize the smartcard in the child process, to avoid inadvertantly
allowing it to inherit an open connection to the smartcard.  As part of
opensc's "Finalize", it dlclose()s its backend module, which in this case is
pcsc-lite.  It appears that pcsc-lite also has an atfork handler installed (I
did not investigate that one, but presumably it is also for the purpose of
closing any open smartcard in the child).  Glibc registers a mechansim,
apparently the same way that C++ destructors are registered, to remove any
atfork handlers that are registered in a module when it is being unloaded.  Now
that there is a (non-recursive) lock around the list of atfork handlers, and
the handlers are called while that lock is held, attempting to unregister an
atfork handler from within an atfork handler callback results in a deadlock.

There is no need for you to bisect - I already tracked down the commit in
question - 27761a1042daf01987e7d79636d0c41511c6df3c - and confirmed that
reverting this solves my deadlock.  If you want a simple test case to reproduce
this, I think the most simple incarnation would be to have an executable and a
shared library.  The executable would register with pthread_atfork(), dlopen()
the shared library, and call something in it which also registers an atfork
handler with pthread_atfork().  The executable would then fork(), and in its
atfork child handler dlclose() the shared library.  This should deadlock with
glibc 2.28 (and 2.29, though I have not yet confirmed this), but work fine with
2.27 and older.

Backtrace:
#0  0x4ec8eb4c in __lll_lock_wait_private () from /lib/libc.so.6
#1  0x4ec8efc6 in __unregister_atfork () from /lib/libc.so.6
#2  0x4ebbd5a9 in __cxa_finalize () from /lib/libc.so.6
#3  0x4dc1a3b1 in __do_global_dtors_aux () from /usr/lib/libpcsclite.so.1
#4  0x4f05ddca in _dl_close_worker () from /lib/ld-linux.so.2
#5  0x4f05e9e2 in _dl_close () from /lib/ld-linux.so.2
#6  0x4ecbdda9 in _dl_catch_exception () from /lib/libc.so.6
#7  0x4ecbde50 in _dl_catch_error () from /lib/libc.so.6
#8  0x4ed3d5e4 in _dlerror_run () from /lib/libdl.so.2
#9  0x4ed3ce9f in dlclose () from /lib/libdl.so.2
#10 0x4ea70664 in sc_dlclose () from /usr/lib/libopensc.so.6
#11 0x4e98d3fb in pcsc_finish () from /usr/lib/libopensc.so.6
#12 0x4e95b259 in sc_release_context () from /usr/lib/libopensc.so.6
#13 0x4eb3ebf2 in C_Finalize () from /usr/lib/opensc-pkcs11.so
#14 0x4eb3ec72 in C_Initialize () from /usr/lib/opensc-pkcs11.so
#15 0x4efe6a1b in __pkcs11h_threading_atfork_child ()
   from /usr/lib/libpkcs11-helper.so.1
#16 0x4ec8f1ed in __run_fork_handlers () from /lib/libc.so.6
#17 0x4ec43aa8 in fork () from /lib/libc.so.6
#18 0x4f00c540 in fork_compat () from /lib/libpthread.so.0
#19 0x125511d5 in openvpn_execve ()
#20 0x12551355 in openvpn_execve_check ()

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]