This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] [BZ#15903] INITFIRST flag does not change fini order (ld.so)
- From: Guillaume Berard <berardgui at gmail dot com>
- To: "Ryan S. Arnold" <ryan dot arnold at gmail dot com>
- Cc: libc-alpha <libc-alpha at sourceware dot org>
- Date: Fri, 6 Sep 2013 14:33:27 +0200
- Subject: Re: [PATCH] [BZ#15903] INITFIRST flag does not change fini order (ld.so)
- Authentication-results: sourceware.org; auth=none
- References: <CAJ3=_khdUcYQ0aj0rRsSDiWTHcjaUQq+JrVzDR0xE6oS=C99-A at mail dot gmail dot com> <CAAKybw9A2u+HdY8WY4Z9HDQm4M=5hdvhVJkn5w9O7GdMujk0nQ at mail dot gmail dot com> <CAJ3=_kggQAAWksNh03_uDSUNBvzMigUKr1i69GQxSz467A8_0A at mail dot gmail dot com> <CAAKybw_vO9zrkbP5C9cgS9+cXt36_a5J870Mn+_S+3LmMkSXEA at mail dot gmail dot com>
On Thu, Sep 5, 2013 at 7:04 PM, Ryan S. Arnold <ryan.arnold@gmail.com> wrote:
> On Thu, Sep 5, 2013 at 8:40 AM, Guillaume Berard <berardgui@gmail.com> wrote:
>> In my fix, if more than one is linked with initfirst, only the last
>> library passed into the dl-open will be considered as the one to be
>> init first, the others will be ignored and the init order will be as
>> if the libraries do not have the initfirst flag. But this was already
>> the case before.
>> Having two libraries linked with initfirst sounds a bit contradictory.
>
> Right, when purposely doing this it doesn't make sense, but it is very
> probable that a library with many dependencies might pull in a few
> libraries that were linked with -Wl,-z,initfirst. I think fixing this
> will take a more thought-out proposal. The patch will certainly be a
> bit more invasive.
>
True, we this patch it is possible to "pollute" the init/fini order if you do
not own all your dependencies...
>> We know we cannot guarantee multiple libraries to be init first. But
>> maybe it would be better to guarantee that all initfirst go before all
>> other inits (sounds more logical).
>> I can try to provide another patch to support multiple initfirst later on.
>
> Sadly the _dl_initfirst pointer points to a link map structure pointer
> which isn't a linked list of libraries marked initfirst.
>
> I think you're right to just focus on correcting the behavior and
> making the first initfirst marked library 'fini' in the correct order
> and dealing with the other issue in a separate patch.
>
> I'm curious whether your patch will work correctly in the following scenario:
>
> libfoo.so.0 and libbar.so.0 both being marked -Wl,-z,initfirst, where
> libfoo.so.0 is an implicit dependency (automatically loaded), and
> libbar.so.1 is a dlopened dependency. Will libfoo.so.0 be initialized
> first, but libbar.so.1 have fini called last (because it's dlopen will
> override, and persist, the existing _dl_initfirst pointer from
> libfoo.so.0)?
>
> I don't think the current code will work properly in this case either,
> but your patch is a step in the right direction (by persisting the
> _dl_initfirst pointer after _dl_init is called in elf/dl-init.c). I
> think that in order to get the proper behavior you'll have to prevent
> elf/dl-load.c:_dl_map_object_from_fd from setting the
> GL(_dl_initfirst) pointer if it's already set.
>
Indeed! I think the best example is to have a normal link to a normal
library and another one dlopened containing the initfirst flag. The
dlopened one will be init last and fini last too :(. I did not think of such
a case. I think the best way to fix this is to store the init order
within a "GL" global variable and just revert this order for getting
the fini order. This way would prevent additional treatment for the
fini order sorting. I will update my changes.
> Are there any other implications of persisting the _dl_initfirst
> pointer? I do wonder why it was initially zeroed after _dl_init was
> called. Perhaps this was to eliminate redundant attempts at
> initialization (which are benign since the load code won't load an
> object twice).
>
I searched for a reason for this but did not find. Before calling init or
fini, we always whether we already called init or not (l->l_init_called)
and don't call it if not needed... But if I create a list containing the init
order, I would not need to keep this pointer anymore.
>> Sorry about the formatting :S.
>
> You can fix it the next time around.
>
> Ryan S. Arnold
Do I need to start a new thread for proposing a new diff for this issue?
Guillaume.