This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
RE: [PATCH 1/3] elf: Allow dlopen of filter object to work [BZ #16272]
- From: David Kilroy <David dot Kilroy at arm dot com>
- To: Florian Weimer <fweimer at redhat dot com>
- Cc: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>, nd <nd at arm dot com>
- Date: Tue, 22 Oct 2019 14:28:47 +0000
- Subject: RE: [PATCH 1/3] elf: Allow dlopen of filter object to work [BZ #16272]
- Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=O5t7yq/jAweQbCyYVlIuHoP7z9qrLAVA5S/r5qo5GNg=; b=UVZE0U+F9D4SJKQcPhozPy1lTXI+YmkdfZfuiBLeOsga3JLsTv0ten9XG1tNa5ecz9/su1lAfPgzxyRMuWg21lpfh0WAce7ADW/Gpdt/wFP3T8FnxYzz3QeI/v3wm7bPl2G2YNOy50r0/PzXust34N6JsfEfiCcK+eGouEeVrDoYA8V2TX/UPuJHWJPh/H5AyDyiODh3pTguboIyvfuofcS1m7kIhhWQh8p/5OYWo9/wNCrFFkGNtv8+qNKZVQKtkZqPHGtrIFczIpHoUypF2WIrjsnzL8QLLaaIYAO4EI1RCyBWnbQxxil8hURZyOd5cViwCNDR4YiPG4ozVcDymQ==
- Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kYN0gbpdye5dEsB9Esj75dKNpYfb8cboZ4YBsaozVrWYgtjC9AGAlG4VlvGjq/e5MipGRGTPIsO3Xzsbc+6dlqNCuaEVtU20uiPbsoB8dOCu3sLumFjVRx2JTP/2De4r90Fmb0GRye+sjMeL8UeERCxT7dpzFyrfGXM5HijK3G3+M81Tlh69S+lFZt4ppYFkrWln2Cz/wRva/JBKRFx2zCJZ3R2PNF+UKqNveUallZze9fKf2vs4pZGEbdUVY6wAc7Uz9onifBRHpIT1mqqAJcOQUinFOcxRdvpunZZbqXYSGxNRKudYOQ2NYx7nIr5pv275eJzdH4/3M+nJKWD3jQ==
- Original-authentication-results: spf=none (sender IP is ) smtp.mailfrom=David dot Kilroy at arm dot com;
- References: <cover.1571301957.git.david.kilroy@arm.com> <4eae391688a6e42b0b75467de265c122e6402668.1571301957.git.david.kilroy@arm.com> <87r23ath25.fsf@oldenburg2.str.redhat.com>
> 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