diff options
author | kib <kib@FreeBSD.org> | 2016-02-08 19:24:13 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-02-08 19:24:13 +0000 |
commit | 42e09be9c23e730d42b331384d128dbba8719c04 (patch) | |
tree | c91cbb77944f06638bce887f736eaeafed34a388 /lib/libc/include | |
parent | 42bcd86bfbff24f6d52e96805b6d8d535c7db051 (diff) | |
download | FreeBSD-src-42e09be9c23e730d42b331384d128dbba8719c04.zip FreeBSD-src-42e09be9c23e730d42b331384d128dbba8719c04.tar.gz |
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
Diffstat (limited to 'lib/libc/include')
-rw-r--r-- | lib/libc/include/libc_private.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 5caf9a3..554f3a2 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -224,6 +224,7 @@ enum { INTERPOS_kevent, INTERPOS_wait6, INTERPOS_ppoll, + INTERPOS_map_stacks_exec, INTERPOS_MAX }; @@ -381,6 +382,7 @@ int _elf_aux_info(int aux, void *buf, int buflen); struct dl_phdr_info; int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __init_elf_aux_vector(void); +void __libc_map_stacks_exec(); void _pthread_cancel_enter(int); void _pthread_cancel_leave(int); |