summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/sigqueue.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-07-12 14:33:37 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-08-08 16:06:48 -0300
commit7b59f9293a2fb93c76701381d0760a3aae50af06 (patch)
treef8925003e34e069658766605a009d00dc71feacc /sysdeps/unix/sysv/linux/sigqueue.c
parenta02cd8e4e091201cb395a805a9f3e2a9981cae37 (diff)
downloadglibc-azanella/bz24595.tar.gz
nptl: Fix deadlock on atfork handler which calls dlclose (BZ#24595)azanella/bz24595
Some real-world cases rely upon that atfork handlers can call functions that might change the atfork handlers, such as dlclose. Since 27761a10 (Refactor atfork handlers), all internal atfork handlers access is protected with a simple lock, not allowing reentrancy. This leads to deadlocks for the aforementioned scenario. Although this specific usage is far from portable (as comment #2 in the bug report), glibc did allow it in the past. This patch fixes by using a double-linked lists along with a lock release while calling the atfork handlers. This is similar to the strategy used on atexit. The list should be kept concise as long as it is invalid to dlclose itself. It should also be safe also call pthread_atfork from a registered callback, although it is up to the caller to handle the resulting list state regarding callback call. Since the new element is added on the end of the list, the prepare handler won't see the new element (since it ran in reverse order), however both the parent and child will. Checked on x86_64-linux-gnu and i686-linux-gnu. * misc/sys/queue.h (TAILQ_FOREACH_SAFE): New macro. * nptl/Makefile [build-shared == yes] (tests): Add tst-atfork3. (modules-names): Add tst-atfork3mod. (tst-atfork3mod.so-no-z-defs, $(objpfx)tst-atfork3:, LDFLAGS-tst-atfork3, $(objpfx)tst-atfork3mod.so, $(objpfx)tst-atfork3.out): New rules. * nptl/register-atfork.c: (__register_atfork, __unregister_atfork, __run_fork_handlers, libc_freeres_fn): Remove usage of dynarray in favor of a double linked list. (atfork_lock): Unlock before calling the callback. (fork_handlers_push_back, fork_handlers_remove, fork_handlers_remove_if, fork_handlers_remove_all): New functions. (fork_handler_list_find): Remove function. * nptl/tst-atfork3.c, nptl/tst-atfork3mod.c: New files. * sysdeps/nptl/fork.h (fork_handler): Remove definition.
Diffstat (limited to 'sysdeps/unix/sysv/linux/sigqueue.c')
0 files changed, 0 insertions, 0 deletions