From b2369ca3ff0cd75a30eb707537f83520c6fb1916 Mon Sep 17 00:00:00 2001
From: Ulrich Drepper <drepper@redhat.com>
Date: Fri, 27 Oct 2006 18:43:38 +0000
Subject: [PATCH] [BZ #3429]

2006-10-27  Ulrich Drepper  <drepper@redhat.com>
	[BZ #3429]
	* elf/dl-open.c (dl_open_worker): Keep holding dl_load_lock until
	we are sure we do not need it anymore for _dl_close.  ALso move
	the asserts inside the lock region.
	Patch mostly by Suzuki <suzuki@in.ibm.com>.
---
 ChangeLog     |  8 ++++++++
 elf/dl-open.c | 21 +++++++++++----------
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 19ebca29ba..d10af5b83c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #3429]
+	* elf/dl-open.c (dl_open_worker): Keep holding dl_load_lock until
+	we are sure we do not need it anymore for _dl_close.  ALso move
+	the asserts inside the lock region.
+	Patch mostly by Suzuki <suzuki@in.ibm.com>.
+
 2006-10-27  Jakub Jelinek  <jakub@redhat.com>
 
 	* elf/dl-lookup.c (_dl_debug_bindings): Remove unised symbol_scope
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 2ae861f9cc..2a891f244d 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -567,15 +567,9 @@ no more namespaces available for dlmopen()"));
   _dl_unload_cache ();
 #endif
 
-  /* Release the lock.  */
-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
-
+  /* See if an error occurred during loading.  */
   if (__builtin_expect (errstring != NULL, 0))
     {
-      /* Some error occurred during loading.  */
-      char *local_errstring;
-      size_t len_errstring;
-
       /* Remove the object from memory.  It may be in an inconsistent
 	 state if relocation failed, for example.  */
       if (args.map)
@@ -595,9 +589,15 @@ no more namespaces available for dlmopen()"));
 	  _dl_close (args.map);
 	}
 
+      assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
+
+      /* Release the lock.  */
+      __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
       /* Make a local copy of the error string so that we can release the
 	 memory allocated for it.  */
-      len_errstring = strlen (errstring) + 1;
+      size_t len_errstring = strlen (errstring) + 1;
+      char *local_errstring;
       if (objname == errstring + len_errstring)
 	{
 	  size_t total_len = len_errstring + strlen (objname) + 1;
@@ -614,14 +614,15 @@ no more namespaces available for dlmopen()"));
       if (malloced)
 	free ((char *) errstring);
 
-      assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
-
       /* Reraise the error.  */
       _dl_signal_error (errcode, objname, NULL, local_errstring);
     }
 
   assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
 
+  /* Release the lock.  */
+  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+
 #ifndef SHARED
   DL_STATIC_INIT (args.map);
 #endif