This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
dlopen vs dl_iterate_phdr thread safety?
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: libc-help at sourceware dot org
- Cc: Andreas Schwab <schwab at suse dot de>
- Date: Thu, 14 Oct 2010 13:40:15 +0200
- Subject: dlopen vs dl_iterate_phdr thread safety?
Hi,
I don't see how dlopen and dl_iterate_phdr are protected from writing/reading link_map
elements in parallel. They protect each other from manipulating the list itself using the
dl_load_write_lock. In dl_map_object_from_fd the lock is taken when calling dl_new_object
which adds a new element to the list. But the content of the element is modified
afterwards without the lock being held what will lead to an inconsistent state as observed
in _Unwind_IteratePhdrCallback called from dl_iterate_phdr.
I'm currently looking at a dump where one thread is writing the phdr field in the link_map
(in _dl_map_object_from_fd) while another one created a copy of the linkmap entry in
dl_iterate_phdr and then crashes in _Unwind_IteratePhdrCallback when dereferencing the
phdr field in the copy as in:
...
for (n = info->dlpi_phnum; --n >= 0; phdr++)
{
if (phdr->p_type == PT_LOAD)
...
_dl_map_object_from_fd:
...
/* Enter the new object in the list of loaded objects. */
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
if (__builtin_expect (l == NULL, 0))
{
#ifdef SHARED
fail_new:
#endif
errstring = N_("cannot create shared object descriptor");
goto call_lose_errno;
}
/* Extract the remaining details we need from the ELF header
and then read in the program header table. */
l->l_entry = header->e_entry;
type = header->e_type;
l->l_phnum = header->e_phnum;
...
Bye,
-Andreas-