This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]