diff options
author | kib <kib@FreeBSD.org> | 2014-06-07 02:45:24 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-06-07 02:45:24 +0000 |
commit | 8d9dc2de3a37d5f757fffb376a780d5081675f2e (patch) | |
tree | 747c00fc9e7b43e6077655fb1d4c318340f89b0e /lib/libthr/thread/thr_rtld.c | |
parent | 218f93e5f8ff4d66b5b39b99db1d741e7067e773 (diff) | |
download | FreeBSD-src-8d9dc2de3a37d5f757fffb376a780d5081675f2e.zip FreeBSD-src-8d9dc2de3a37d5f757fffb376a780d5081675f2e.tar.gz |
MFC r266609:
Change the _rtld_atfork() to lock the bind lock in write mode.
Diffstat (limited to 'lib/libthr/thread/thr_rtld.c')
-rw-r--r-- | lib/libthr/thread/thr_rtld.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c index fd379d6..5d89988 100644 --- a/lib/libthr/thread/thr_rtld.c +++ b/lib/libthr/thread/thr_rtld.c @@ -32,10 +32,12 @@ */ #include <sys/cdefs.h> #include <sys/mman.h> +#include <sys/syscall.h> #include <link.h> #include <stdlib.h> #include <string.h> +#include "libc_private.h" #include "rtld_lock.h" #include "thr_private.h" @@ -207,7 +209,24 @@ _thr_rtld_init(void) li.thread_set_flag = _thr_rtld_set_flag; li.thread_clr_flag = _thr_rtld_clr_flag; li.at_fork = NULL; - + + /* + * Preresolve the symbols needed for the fork interposer. We + * call _rtld_atfork_pre() and _rtld_atfork_post() with NULL + * argument to indicate that no actual locking inside the + * functions should happen. Neither rtld compat locks nor + * libthr rtld locks cannot work there: + * - compat locks do not handle the case of two locks taken + * in write mode (the signal mask for the thread is corrupted); + * - libthr locks would work, but locked rtld_bind_lock prevents + * symbol resolution for _rtld_atfork_post. + */ + _rtld_atfork_pre(NULL); + _rtld_atfork_post(NULL); + _malloc_prefork(); + _malloc_postfork(); + syscall(SYS_getpid); + /* mask signals, also force to resolve __sys_sigprocmask PLT */ _thr_signal_block(curthread); _rtld_thread_init(&li); |