about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-close.c24
-rw-r--r--elf/dl-lookup.c6
-rw-r--r--elf/dl-open.c10
-rw-r--r--elf/dl-runtime.c17
-rw-r--r--elf/dl-sym.c7
5 files changed, 41 insertions, 23 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 84e57e09d0..bfcceea4bc 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -30,6 +30,7 @@
 #include <ldsodefs.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sysdep-cancel.h>
 
 
 /* Type of the constructor functions.  */
@@ -419,16 +420,21 @@ _dl_close (void *_map)
 
 	      struct r_scoperec *old = imap->l_scoperec;
 
-	      __rtld_mrlock_change (imap->l_scoperec_lock);
-	      imap->l_scoperec = newp;
-	      __rtld_mrlock_done (imap->l_scoperec_lock);
-
-	      if (catomic_increment_val (&old->nusers) != 1)
+	      if (SINGLE_THREAD_P)
+		imap->l_scoperec = newp;
+	      else
 		{
-		  old->remove_after_use = true;
-		  old->notify = true;
-		  if (catomic_decrement_val (&old->nusers) != 0)
-		    __rtld_waitzero (old->nusers);
+		  __rtld_mrlock_change (imap->l_scoperec_lock);
+		  imap->l_scoperec = newp;
+		  __rtld_mrlock_done (imap->l_scoperec_lock);
+
+		  if (atomic_increment_val (&old->nusers) != 1)
+		    {
+		      old->remove_after_use = true;
+		      old->notify = true;
+		      if (atomic_decrement_val (&old->nusers) != 0)
+			__rtld_waitzero (old->nusers);
+		    }
 		}
 
 	      /* No user anymore, we can free it now.  */
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 7cfcc620a7..72381698db 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -207,7 +207,11 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 
 
 /* Search loaded objects' symbol tables for a definition of the symbol
-   UNDEF_NAME, perhaps with a requested version for the symbol.  */
+   UNDEF_NAME, perhaps with a requested version for the symbol.
+
+   We must never have calls to the audit functions inside this function
+   or in any function which gets called.  If this would happen the audit
+   code might create a thread which can throw off all the scope locking.  */
 lookup_t
 internal_function
 _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 35712b5ac0..85b9637305 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -31,6 +31,7 @@
 #include <ldsodefs.h>
 #include <bp-sym.h>
 #include <caller.h>
+#include <sysdep-cancel.h>
 
 #include <dl-dst.h>
 
@@ -423,15 +424,20 @@ dl_open_worker (void *a)
 
 	      if (old == &imap->l_scoperec_mem)
 		imap->l_scoperec = newp;
+	      else if (SINGLE_THREAD_P)
+		{
+		  imap->l_scoperec = newp;
+		  free (old);
+		}
 	      else
 		{
 		  __rtld_mrlock_change (imap->l_scoperec_lock);
 		  imap->l_scoperec = newp;
 		  __rtld_mrlock_done (imap->l_scoperec_lock);
 
-		  catomic_increment (&old->nusers);
+		  atomic_increment (&old->nusers);
 		  old->remove_after_use = true;
-		  if (catomic_decrement_val (&old->nusers) == 0)
+		  if (atomic_decrement_val (&old->nusers) == 0)
 		    /* No user, we can free it here and now.  */
 		    free (old);
 		}
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 05fd974bf5..8bf5b89eb6 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <sys/param.h>
 #include <ldsodefs.h>
+#include <sysdep-cancel.h>
 #include "dynamic-link.h"
 
 #if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@@ -93,11 +94,11 @@ _dl_fixup (
 	}
 
       struct r_scoperec *scoperec = l->l_scoperec;
-      if (l->l_type == lt_loaded)
+      if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
 	{
 	  __rtld_mrlock_lock (l->l_scoperec_lock);
 	  scoperec = l->l_scoperec;
-	  catomic_increment (&scoperec->nusers);
+	  atomic_increment (&scoperec->nusers);
 	  __rtld_mrlock_unlock (l->l_scoperec_lock);
 	}
 
@@ -106,8 +107,8 @@ _dl_fixup (
 				    ELF_RTYPE_CLASS_PLT,
 				    DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
-      if (l->l_type == lt_loaded
-	  && catomic_decrement_val (&scoperec->nusers) == 0
+      if (l->l_type == lt_loaded && !SINGLE_THREAD_P
+	  && atomic_decrement_val (&scoperec->nusers) == 0
 	  && __builtin_expect (scoperec->remove_after_use, 0))
 	{
 	  if (scoperec->notify)
@@ -195,11 +196,11 @@ _dl_profile_fixup (
 	    }
 
 	  struct r_scoperec *scoperec = l->l_scoperec;
-	  if (l->l_type == lt_loaded)
+	  if (l->l_type == lt_loaded && !SINGLE_THREAD_P)
 	    {
 	      __rtld_mrlock_lock (l->l_scoperec_lock);
 	      scoperec = l->l_scoperec;
-	      catomic_increment (&scoperec->nusers);
+	      atomic_increment (&scoperec->nusers);
 	      __rtld_mrlock_unlock (l->l_scoperec_lock);
 	    }
 
@@ -208,8 +209,8 @@ _dl_profile_fixup (
 					ELF_RTYPE_CLASS_PLT,
 					DL_LOOKUP_ADD_DEPENDENCY, NULL);
 
-	  if (l->l_type == lt_loaded
-	      && catomic_decrement_val (&scoperec->nusers) == 0
+	  if (l->l_type == lt_loaded && !SINGLE_THREAD_P
+	      && atomic_decrement_val (&scoperec->nusers) == 0
 	      && __builtin_expect (scoperec->remove_after_use, 0))
 	    {
 	      if (scoperec->notify)
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 43933466b4..34d75a1a67 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -25,6 +25,7 @@
 #include <dlfcn.h>
 #include <ldsodefs.h>
 #include <dl-hash.h>
+#include <sysdep-cancel.h>
 #ifdef USE_TLS
 # include <dl-tls.h>
 #endif
@@ -115,7 +116,7 @@ do_sym (void *handle, const char *name, void *who,
 	 the initial binary.  And then the more complex part
 	 where the object is dynamically loaded and the scope
 	 array can change.  */
-      if (match->l_type != lt_loaded)
+      if (match->l_type != lt_loaded || SINGLE_THREAD_P)
 	result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
 					   match->l_scoperec->scope, vers, 0,
 					   flags | DL_LOOKUP_ADD_DEPENDENCY,
@@ -124,7 +125,7 @@ do_sym (void *handle, const char *name, void *who,
 	{
 	  __rtld_mrlock_lock (match->l_scoperec_lock);
 	  struct r_scoperec *scoperec = match->l_scoperec;
-	  catomic_increment (&scoperec->nusers);
+	  atomic_increment (&scoperec->nusers);
 	  __rtld_mrlock_unlock (match->l_scoperec_lock);
 
 	  struct call_dl_lookup_args args;
@@ -141,7 +142,7 @@ do_sym (void *handle, const char *name, void *who,
 	  int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
 					  call_dl_lookup, &args);
 
-	  if (catomic_decrement_val (&scoperec->nusers) == 0
+	  if (atomic_decrement_val (&scoperec->nusers) == 0
 	      && __builtin_expect (scoperec->remove_after_use, 0))
 	    {
 	      if (scoperec->notify)