diff options
author | Andreas Schneider <asn@samba.org> | 2017-11-27 11:00:54 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2017-12-04 12:23:47 +0100 |
commit | 3547fdfc094f4588375cb7b1716461f8f328b643 (patch) | |
tree | f36cbf07c210e81fb334943e0a35850b70ab0413 /src | |
parent | 570930cff3511054eeeea1a3e5e8155946b501ef (diff) | |
download | socket_wrapper-3547fdfc094f4588375cb7b1716461f8f328b643.tar.gz socket_wrapper-3547fdfc094f4588375cb7b1716461f8f328b643.tar.xz socket_wrapper-3547fdfc094f4588375cb7b1716461f8f328b643.zip |
swrap: Avoid symbol binding deadlocks during fork
If there is a signal handler defined, e.g. for SIGCHILD and this signal
handler is called during pthread_atfork() has just locked all mutexes
and we want to check if a symbol is bound, we end up in a deadlock.
(gdb) bt
0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
1 0x00007fe48837aef5 in __GI___pthread_mutex_lock (mutex=0x7fe4889a71c0 <libc_symbol_binding_mutex>) at ../nptl/pthread_mutex_lock.c:80
2 0x00007fe48879b2f1 in libc_write (fd=14, buf=0x7ffdad6436e8, count=8) at /home/asn/workspace/projects/socket_wrapper/src/socket_wrapper.c:1070
3 0x00007fe4887a21cb in swrap_write (s=14, buf=0x7ffdad6436e8, len=8) at /home/asn/workspace/projects/socket_wrapper/src/socket_wrapper.c:5137
4 0x00007fe4887a2359 in write (s=14, buf=0x7ffdad6436e8, len=8) at /home/asn/workspace/projects/socket_wrapper/src/socket_wrapper.c:5171
5 0x00007fe48713e5f2 in tevent_common_wakeup_fd (fd=14) at ../lib/tevent/tevent.c:959
6 0x00007fe48713e61f in tevent_common_wakeup (ev=ev@entry=0x55d04922e280) at ../lib/tevent/tevent.c:975
7 0x00007fe487141d38 in tevent_common_signal_handler (signum=<optimized out>) at ../lib/tevent/tevent_signal.c:109
8 <signal handler called>
9 0x00007fe4844de081 in __libc_fork () at ../sysdeps/nptl/fork.c:135
10 0x000055d047e8ddb3 in smbd_accept_connection (ev=0x55d04922e280, fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>)
at ../source3/smbd/server.c:992
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/socket_wrapper.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index f6d7e24..539d27d 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -671,28 +671,34 @@ static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name) } #define swrap_bind_symbol_libc(sym_name) \ - SWRAP_LOCK(libc_symbol_binding); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \ - } \ - SWRAP_UNLOCK(libc_symbol_binding) + SWRAP_LOCK(libc_symbol_binding); \ + if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ + swrap.libc.symbols._libc_##sym_name.obj = \ + _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \ + } \ + SWRAP_UNLOCK(libc_symbol_binding); \ + } #define swrap_bind_symbol_libsocket(sym_name) \ - SWRAP_LOCK(libc_symbol_binding); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \ - } \ - SWRAP_UNLOCK(libc_symbol_binding) + SWRAP_LOCK(libc_symbol_binding); \ + if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ + swrap.libc.symbols._libc_##sym_name.obj = \ + _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \ + } \ + SWRAP_UNLOCK(libc_symbol_binding); \ + } #define swrap_bind_symbol_libnsl(sym_name) \ - SWRAP_LOCK(libc_symbol_binding); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - swrap.libc.symbols._libc_##sym_name.obj = \ - _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \ - } \ - SWRAP_UNLOCK(libc_symbol_binding) + SWRAP_LOCK(libc_symbol_binding); \ + if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ + swrap.libc.symbols._libc_##sym_name.obj = \ + _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \ + } \ + SWRAP_UNLOCK(libc_symbol_binding); \ + } /**************************************************************************** * IMPORTANT |