From 42e09be9c23e730d42b331384d128dbba8719c04 Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 8 Feb 2016 19:24:13 +0000 Subject: If libthr.so is dlopened without RTLD_GLOBAL flag, the libthr symbols do not participate in the global symbols namespace, but rtld locks are still replaced and functions are interposed. In particular, __pthread_map_stacks_exec is resolved to the libc version. If a library is loaded later, which requires adjustment of the stack protection mode, rtld calls into libc __pthread_map_stacks_exec due to the symbols scope. The libc version might recurse into binder and recursively acquire rtld bind lock, causing the hang. Make libc __pthread_map_stacks_exec() interposed, which synchronizes rtld locks and version of the stack exec hook when libthr loaded, regardless of the symbol scope control or symbol resolution order. The __pthread_map_stacks_exec() symbol is removed from the private version in libthr since libc symbol now operates correctly in presence of libthr. Reported and tested by: markj Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- lib/libthr/thread/thr_private.h | 2 ++ lib/libthr/thread/thr_stack.c | 3 +-- lib/libthr/thread/thr_syscalls.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/libthr/thread') diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 0ba123d..6020e07 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -927,6 +927,8 @@ int __thr_sigwait(const sigset_t *set, int *sig); int __thr_sigwaitinfo(const sigset_t *set, siginfo_t *info); int __thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp); +void __thr_map_stacks_exec(void); + struct _spinlock; void __thr_spinunlock(struct _spinlock *lck); void __thr_spinlock(struct _spinlock *lck); diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c index e5d149e..74e1329 100644 --- a/lib/libthr/thread/thr_stack.c +++ b/lib/libthr/thread/thr_stack.c @@ -161,9 +161,8 @@ singlethread_map_stacks_exec(void) rlim.rlim_cur, _rtld_get_stack_prot()); } -void __pthread_map_stacks_exec(void); void -__pthread_map_stacks_exec(void) +__thr_map_stacks_exec(void) { struct pthread *curthread, *thrd; struct stack *st; diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c index 7c05697..712249b 100644 --- a/lib/libthr/thread/thr_syscalls.c +++ b/lib/libthr/thread/thr_syscalls.c @@ -652,6 +652,7 @@ __thr_interpose_libc(void) SLOT(kevent); SLOT(wait6); SLOT(ppoll); + SLOT(map_stacks_exec); #undef SLOT *(__libc_interposing_slot( INTERPOS__pthread_mutex_init_calloc_cb)) = -- cgit v1.1