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 <sys/sysctl.h>
 #include <link.h>
 #include <stddef.h>
+#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)) =
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to