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: "Ryan S. Arnold" <ryan dot arnold at gmail dot com>
- To: Guillaume Berard <berardgui at gmail dot com>
- Cc: libc-alpha <libc-alpha at sourceware dot org>
- Date: Fri, 6 Sep 2013 13:08:53 -0500
- 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> <CAJ3=_kjy-vO4XZ_J1JPwy-u6nzDEeGSRUX2pfh8stPCcfwDkZw at mail dot gmail dot com>
On Fri, Sep 6, 2013 at 7:33 AM, Guillaume Berard <berardgui@gmail.com> wrote:
> 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...
I think currently it doesn't conform to the documentation anyway.
>
>>> 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.
For a future patch, yes that would work. For the current patch,
wouldn't simply disallowing a second initfirst setting accomplish what
you want?
>
>> 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.
Which pointer, l->l_init_called or _dl_initfirst?
> Do I need to start a new thread for proposing a new diff for this issue?
If the scope changes and the subject of the current email is no longer
relevant sure.
Ryan