about summary refs log tree commit diff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2010-05-03 08:08:28 -0700
committerUlrich Drepper <drepper@redhat.com>2010-05-03 08:08:28 -0700
commit5a2a1d75043138e696222ced4560de2fb90b8024 (patch)
tree76c2da1388b8787ebabb9e61cf27d7510d1f5a7b /elf/dl-load.c
parentc739ec3d81a34a87d8ae1276eab4f5880afc3476 (diff)
downloadglibc-5a2a1d75043138e696222ced4560de2fb90b8024.tar.gz
glibc-5a2a1d75043138e696222ced4560de2fb90b8024.tar.xz
glibc-5a2a1d75043138e696222ced4560de2fb90b8024.zip
Don't deadlock in __dl_iterate_phdr while (un)loading objects.
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index d8f9131dd6..0adddf5aaa 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -803,6 +803,8 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
     (void) __close (fd);
   if (l != NULL)
     {
+      /* We modify the list of loaded objects.  */
+      __rtld_lock_lock_recursive (GL(dl_load_write_lock));
       /* Remove the stillborn object from the list and free it.  */
       assert (l->l_next == NULL);
       if (l->l_prev == NULL)
@@ -813,6 +815,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
 	l->l_prev->l_next = NULL;
       --GL(dl_ns)[l->l_ns]._ns_nloaded;
       free (l);
+      __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
     }
   free (realname);