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

RE: [PATCH 1/3] elf: Allow dlopen of filter object to work [BZ #16272]


> Florian Weimer
> 
> * David Kilroy:
> 
> > diff --git a/elf/dl-open.c b/elf/dl-open.c index a9fd4cb..7fcfdc0
> > 100644
> > --- a/elf/dl-open.c
> > +++ b/elf/dl-open.c
> > @@ -305,22 +305,25 @@ dl_open_worker (void *a)
> >       allows IFUNC relocations to work and it also means copy
> >       relocation of dependencies are if necessary overwritten.  */
> >    unsigned int nmaps = 0;
> > -  struct link_map *l = new;
> > +  unsigned int j = 0;
> > +  struct link_map *l =  new->l_initfini[0];
> >    do
> >      {
> >        if (! l->l_real->l_relocated)
> >  	++nmaps;
> > -      l = l->l_next;
> > +      l = new->l_initfini[++j];
> >      }
> >    while (l != NULL);
> > +  /* Stack allocation is limited by the number of loaded objects.
> */
> >    struct link_map *maps[nmaps];
> >    nmaps = 0;
> > -  l = new;
> > +  j = 0;
> > +  l = new->l_initfini[0];
> >    do
> >      {
> >        if (! l->l_real->l_relocated)
> >  	maps[nmaps++] = l;
> > -      l = l->l_next;
> > +      l = new->l_initfini[++j];
> >      }
> >    while (l != NULL);
> >    _dl_sort_maps (maps, nmaps, NULL, false);
> 
> I have much more trouble ascertaining whether this change is correct.
> Are we certain that new->l_initfini is not a subset of the maps that
> have been loaded?

I've tried to double check this. Having not seen this code until recently, I
may have some of the details wrong but I've to summarized what I think is
the case below.

In short, as far as I can tell all the libraries in the l_next list also exist
in l_initfini.

If anyone knows otherwise, I'd appreciate a pointer.



Regards,

Dave.

In dl_open_worker the field new->l_next is populated by _dl_map_object_from_fd
(via _dl_map_object), where it calls _dl_add_to_namespace_list. Every loaded
object should be added to the global list.

New->l_initfini is populated in _dl_object_map_deps()

* The list `known` is populated with the binary, followed by preloads

** note: for the call from dlopen_worker, preloads is set to NULL

* dependencies are added to `known`

** each dependency is opened (via openaux and _dl_map_object), so the l_next
   list contains all new dependencies.

** each dependency gets its own map->l_initfini populated

* If the object is an aux or filter object

** the filtee is inserted before the filter in `known`.

** the l_next list is modified to put the filtee before the filter

* l_initfini for the main binary is then redone (even if previously loaded)

** It gets each library in `known`, excluding those with l_faked set
   (library not found in trace mode)

*** l_faked is only set to 1 in dl-load.c:_dl_map_object:2194

** l_initfini is sorted. Note that the sort keeps the main object at the
   head of l_initfini, unlike the sort in _dl_open_worker


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