Are ifuncs intended to be allowed to resolve to symbols in another DSO?
Florian Weimer
fweimer@redhat.com
Fri Feb 21 13:28:00 GMT 2020
* Carlos O'Donell:
> On 2/3/20 3:06 PM, Florian Weimer wrote:
>> * Carlos O'Donell:
>>
>>> If an IFUNC resolver calls a function which is not yet resolved then
>>> isn't that a defect in the IFUNC resolver?
>>
>> There is a position that an IFUNC resolver must not use any non-local
>> relocations. (We must support some relocations for IFUNCs on
>> !PI_STATIC_AND_HIDDEN targets.) In this case, yes, such a dependencies
>> would be a bug because all external dependencies are bugs.
>
> Just so I understand the position is, to simplify the implementation, that
> IFUNC resolvers must not use any non-local relocations?
It means no location depedencies at all for PI_STATIC_AND_HIDDEN
targets. I think this is actually the current consensus, as expressed
in the implementation.
I don't know how to express this requirement for !PI_STATIC_AND_HIDDEN
targets. Fangrui Song explained potential problems there.
We probably should not add IFUNC supports for targets that are not
PI_STATIC_AND_HIDDEN. If every function call and data reference goes
through a GOT-like construct, that can never work with IFUNCs with
symbol references that do not strictly follow the order of dependencies
and thus relocation processing in the dynamic loader.
> I don't think that would be useful since you'd want to call many libc
> functions from the resolver itself and so you would have calls in the
> resolver that could call through a GOT entry that has a relocation
> against an external symbol in another DSO e.g. libc.so.6.
ELF constructors are another concern here. Relocation processing
happens before they run, so such calls will see uninitialized libraries.
We can make this work for libc.so.6, but currently, it's not very
reliable, especially for things that user may actually want to use, like
getenv.
>> On the other hand, in glibc, we could get rid of many IFUNC resolvers
>> which violate this rule only after changing the loader that eliminated
>> their need for them. Other IFUNCs that do not follow this rule do not
>> have this luxury.
>
> I don't quite parse your first setnence here, could you expand on that
> please?
The toolchain currently does not permit IFUNC resolvers which depend on
most run-time relocations for work. libpthread violated that
requirement for vfork (and earlier for other functions).
>>> The code which contains such an IFUNC should have had a DT_NEEDED entry
>>> on all objects to which the resolver called into?
>>
>> This does not help with symbol interposition.
>
> What exact problem does symbol interposition cause?
It introduces symbol dependencies which are not reflected in the
DT_NEEDED dependencies. This means that the relocation order chosen by
the dynamic loader does not meet the actual requirements of IFUNC
resolvers.
>>> I like solutions that ensure that IFUNC resolvers, which are just foreign
>>> functions, run at a stage *after* their own dependencies have been resolved,
>>> but before their own initializers have run.
>>
>> Lazy binding achieves this because it implicitly tracks this dependency
>> information. For eager binding, we simply do not have this information.
>> Hence my patch for delayed relocation processing. But it does not solve
>> the problem completely, of course.
>
> The dependencies are explicitly tracked by DT_NEEDED.
Not for symbol interposition.
Thanks,
Florian
More information about the Libc-alpha
mailing list