From owner-svn-src-all@freebsd.org Mon Feb 8 19:24:15 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 867F1AA2EEB; Mon, 8 Feb 2016 19:24:15 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 43D35B9E; Mon, 8 Feb 2016 19:24:15 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u18JOEJt006082; Mon, 8 Feb 2016 19:24:14 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u18JODcb006075; Mon, 8 Feb 2016 19:24:13 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201602081924.u18JODcb006075@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Mon, 8 Feb 2016 19:24:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295407 - in head/lib: libc/gen libc/include libc/sys libthr libthr/thread X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Feb 2016 19:24:15 -0000 Author: kib Date: Mon Feb 8 19:24:13 2016 New Revision: 295407 URL: https://svnweb.freebsd.org/changeset/base/295407 Log: 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 Modified: head/lib/libc/gen/elf_utils.c head/lib/libc/include/libc_private.h head/lib/libc/sys/interposing_table.c head/lib/libthr/pthread.map head/lib/libthr/thread/thr_private.h head/lib/libthr/thread/thr_stack.c head/lib/libthr/thread/thr_syscalls.c Modified: head/lib/libc/gen/elf_utils.c ============================================================================== --- head/lib/libc/gen/elf_utils.c Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libc/gen/elf_utils.c Mon Feb 8 19:24:13 2016 (r295407) @@ -32,6 +32,7 @@ #include #include #include +#include "libc_private.h" int __elf_phdr_match_addr(struct dl_phdr_info *, void *); void __pthread_map_stacks_exec(void); @@ -54,9 +55,8 @@ __elf_phdr_match_addr(struct dl_phdr_inf return (i != phdr_info->dlpi_phnum); } -#pragma weak __pthread_map_stacks_exec void -__pthread_map_stacks_exec(void) +__libc_map_stacks_exec(void) { int mib[2]; struct rlimit rlim; @@ -75,3 +75,10 @@ __pthread_map_stacks_exec(void) rlim.rlim_cur, _rtld_get_stack_prot()); } +#pragma weak __pthread_map_stacks_exec +void +__pthread_map_stacks_exec(void) +{ + + ((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); +} Modified: head/lib/libc/include/libc_private.h ============================================================================== --- head/lib/libc/include/libc_private.h Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libc/include/libc_private.h Mon Feb 8 19:24:13 2016 (r295407) @@ -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, in 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); Modified: head/lib/libc/sys/interposing_table.c ============================================================================== --- head/lib/libc/sys/interposing_table.c Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libc/sys/interposing_table.c Mon Feb 8 19:24:13 2016 (r295407) @@ -78,6 +78,7 @@ interpos_func_t __libc_interposing[INTER SLOT(kevent, __sys_kevent), SLOT(wait6, __sys_wait6), SLOT(ppoll, __sys_ppoll), + SLOT(map_stacks_exec, __libc_map_stacks_exec), }; #undef SLOT Modified: head/lib/libthr/pthread.map ============================================================================== --- head/lib/libthr/pthread.map Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libthr/pthread.map Mon Feb 8 19:24:13 2016 (r295407) @@ -295,8 +295,6 @@ FBSDprivate_1.0 { _thread_size_key; _thread_state_running; _thread_state_zoombie; - - __pthread_map_stacks_exec; }; FBSD_1.1 { Modified: head/lib/libthr/thread/thr_private.h ============================================================================== --- head/lib/libthr/thread/thr_private.h Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libthr/thread/thr_private.h Mon Feb 8 19:24:13 2016 (r295407) @@ -927,6 +927,8 @@ int __thr_sigwait(const sigset_t *set, i 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); Modified: head/lib/libthr/thread/thr_stack.c ============================================================================== --- head/lib/libthr/thread/thr_stack.c Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libthr/thread/thr_stack.c Mon Feb 8 19:24:13 2016 (r295407) @@ -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; Modified: head/lib/libthr/thread/thr_syscalls.c ============================================================================== --- head/lib/libthr/thread/thr_syscalls.c Mon Feb 8 18:57:06 2016 (r295406) +++ head/lib/libthr/thread/thr_syscalls.c Mon Feb 8 19:24:13 2016 (r295407) @@ -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)) =