This is the mail archive of the glibc-bugs@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]

[Bug dynamic-link/13579] do_lookup_x may access dangling memory


http://sourceware.org/bugzilla/show_bug.cgi?id=13579

--- Comment #8 from Carlos O'Donell <carlos_odonell at mentor dot com> 2012-04-06 08:48:59 UTC ---
(In reply to comment #6)
> +             /* We can't remove the l_initfini memory because
> +                it's shared with l_searchlist.r_list.  We don't clear
> +                the latter so when we dlopen this object again that
> +                entry would point to stale memory.  And we don't want
> +                to recompute it as it would involve a new call to
> +                map_object_deps.
> +             _dl_scope_free (oldp); */

Thanks this is starting to explain the problem.

Why is l_searchlist.r_list sharing the memory of l_initfini, they each have
nothing to do with eachother, other than the fact that they are both of type
`struct link_map **`.

In dl-close.c I see this:
~~~
318           if (imap->l_searchlist.r_list == NULL && imap->l_initfini !=
NULL)
319             {
320               /* The object is still used.  But one of the objects we are
321                  unloading right now is responsible for loading it.  If
322                  the current object does not have it's own scope yet we
323                  have to create one.  This has to be done before running
324                  the finalizers.
325
326                  To do this count the number of dependencies.  */
327               unsigned int cnt;
328               for (cnt = 1; imap->l_initfini[cnt] != NULL; ++cnt)
329                 ;
330
331               /* We simply reuse the l_initfini list.  */
332               imap->l_searchlist.r_list = &imap->l_initfini[cnt + 1];
333               imap->l_searchlist.r_nlist = cnt;
334
335               new_list = &imap->l_searchlist;
336             }
~~~
Which doesn't make any sense to me. Why are we resusing l_initfini for what
appears to be a completely orthogonal purpose?

However, in dl-deps.c(_dl_map_object_deps) we clearly get:
~~~
513   /* Store the search list we built in the object.  It will be used for
514      searches in the scope of this object.  */
515   struct link_map **l_initfini =
516     (struct link_map **) malloc ((2 * nlist + 1)
517                                  * sizeof (struct link_map *));
518   if (l_initfini == NULL)
519     _dl_signal_error (ENOMEM, map->l_name, NULL,
520                       N_("cannot allocate symbol search list"));
521
522
523   map->l_searchlist.r_list = &l_initfini[nlist + 1];
524   map->l_searchlist.r_nlist = nlist;
~~~
Which allocates a list of 2*nlist+1 size, and points l_searchlist.r_list into
nlist+1 which is 2 beyond nlist pointers, and we see why it does this in a
second...

Then we point l_initfini at the start of the memory block and terminate it:
~~~
687   /* Terminate the list of dependencies.  */
688   l_initfini[nlist] = NULL;
689   atomic_write_barrier ();
690   map->l_initfini = l_initfini;
~~~

So we have a contiguous allocation of pointers split in two with a NULL entry:

|A---------------|NULL|B-----------------|

Where map->l_initfini points to A [0,nlist], including NULL, it is nlist+1
pointers.

Where map->l_searchlist.r_list points to B [nlist+1,2*nlist+1] which is only
nlist pointers.

Obviously freeing l_initfini is impossible unless you also clear
l_searchlist.r_list, and then you'd have to recompute the r_list.

I need to think about this some more.

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


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