diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-07-12 14:33:37 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-08-08 16:06:48 -0300 |
commit | 7b59f9293a2fb93c76701381d0760a3aae50af06 (patch) | |
tree | f8925003e34e069658766605a009d00dc71feacc /io/fts.h | |
parent | a02cd8e4e091201cb395a805a9f3e2a9981cae37 (diff) | |
download | glibc-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 'io/fts.h')
0 files changed, 0 insertions, 0 deletions