diff options
author | Andreas Krebbel <Andreas.Krebbel@de.ibm.com> | 2010-10-26 00:23:14 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2010-10-26 00:23:14 -0400 |
commit | f09677388a44cd1460f8986ef1b096c73bd5b958 (patch) | |
tree | be86216cc5afa7ce2e708c53fef206468b675bd9 /elf/dl-load.c | |
parent | dbf3a06904168417a05882a871342e7a9ee3b383 (diff) | |
download | glibc-f09677388a44cd1460f8986ef1b096c73bd5b958.tar glibc-f09677388a44cd1460f8986ef1b096c73bd5b958.tar.gz glibc-f09677388a44cd1460f8986ef1b096c73bd5b958.tar.bz2 glibc-f09677388a44cd1460f8986ef1b096c73bd5b958.zip |
Fix concurrency problem between dl_open and dl_iterate_phdr
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r-- | elf/dl-load.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c index aa8738f016..4c14f08e55 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -798,22 +798,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, /* The file might already be closed. */ if (fd != -1) (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) - /* No other module loaded. This happens only in the static library, - or in rtld under --verify. */ - GL(dl_ns)[l->l_ns]._ns_loaded = NULL; - else - 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 (l); free (realname); if (r != NULL) @@ -898,6 +883,9 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, never be unloaded. */ __close (fd); + /* Add the map for the mirrored object to the object list. */ + _dl_add_to_namespace_list (l, nsid); + return l; } #endif @@ -1492,6 +1480,9 @@ cannot enable executable stack as shared object requires"); add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB]) + l->l_info[DT_SONAME]->d_un.d_val)); + /* Now that the object is fully initialized add it to the object list. */ + _dl_add_to_namespace_list (l, nsid); + #ifdef SHARED /* Auditing checkpoint: we have a new object. */ if (__builtin_expect (GLRO(dl_naudit) > 0, 0) @@ -2216,7 +2207,7 @@ _dl_map_object (struct link_map *loader, const char *name, have. */ static const Elf_Symndx dummy_bucket = STN_UNDEF; - /* Enter the new object in the list of loaded objects. */ + /* Allocate a new object map. */ if ((name_copy = local_strdup (name)) == NULL || (l = _dl_new_object (name_copy, name, type, loader, mode, nsid)) == NULL) @@ -2234,6 +2225,9 @@ _dl_map_object (struct link_map *loader, const char *name, l->l_nbuckets = 1; l->l_relocated = 1; + /* Enter the object in the object list. */ + _dl_add_to_namespace_list (l, nsid); + return l; } else if (found_other_class) |