Web lists-archives.com

Re: dlopen()ing shared libraries considered harmful (was Re: Depends/Recommends from libraries)




On 03/26/2017 09:37 AM, Florian Weimer wrote:
> * Guillem Jover:
> 
>>> dlopen()ing dependencies in the way that is most commonly implemented,
>>> with dlopen("libimobiledevice.so.6") and dlsym(handle, "idevice_new")
>>> or similar, has some practical problems for Debian:
>>>
>>> * The libraries used aren't visible to dpkg-shlibdeps. The maintainer has
>>>   to know what dlopen() calls the code will make, and either hard-code an
>>>   appropriate Depends (or in this case Recommends), or link a dummy
>>>   executable against the same things that are dlopen()ed (as is done
>>>   in packages like wine and openal-soft) and use that for dpkg-shlibdeps.
>>>   Either way, they have to remember to update it for every new upstream
>>>   release. This is the sort of tedious-but-subtle work that we automate
>>>   because otherwise it will inevitably be incorrect after a few releases.
>>>
>>> * The exact symbols used aren't visible to dpkg-shlibdeps. The maintainer
>>>   has to hard-code a version number that has all the required symbols.
>>>   Again, this is the sort of thing that we automate because it will
>>>   inevitably go wrong if done manually.
>>
>> And:
>>
>>  * Because the shared library SONAME is hard-coded in both code and
>>    packaging metadata, whenever there's a transition with a SOVERSION
>>    bump that could have been handled with a simple mass binNMU, instead
>>    it requires manual intervention to patch those, while making sure it
>>    still works due to the points above.

At least for Wine the SONAME of dlopen'ed libraries is not hardcoded,
but computed during configure.  We then grep these SONAMEs and build a
helper elf binary to compute the needed dependencies with dpkg-shlibdeps.

So this solution is fully automatic both upstream and in the packaging,
therefore it allows for binNMUs.

Building the helper binary could even be omitted if someone implements
this in dpkg-shlibdeps (see #596715 "dpkg-shlibdeps: Please allow to
manually add library dependencies via shlibdeps").

Greets
jre


> And:
> 
> * For regular dynamic linking, the static linker (ld) puts the default
>   symbol version seen in the linked DSO into the object which refers
>   to that DSO, so that each symbol refers to a fixed symbol version.
>   This symbol version matches the header file contents of the library
>   at the time, and is consistent with the link.  With dlopen/dlsym,
>   this step does not happen, and dlsym will pick the newest (*) symbol
>   version.  This version might not match what was in the header files
>   at compilation time.  (Theoretically, it would be possible to
>   determine the applicable symbol version at compile time and use
>   dlvsym, but no one does that.)
> 
> (*) Not quite because we have a bug:
>     <https://sourceware.org/bugzilla/show_bug.cgi?id=12977>
> 
>>> The pedantically correct way to have weak library dependencies is this
>>> multi-level chain of linking, analogous to what is documented for APIs
>>> that wrap dlopen() such as libltdl and GLib's GModule:
>>>
>>>     - eventual API user, e.g. /usr/bin/gnome-software
>>>       dlopen()s:
>>>         - a plugin intended to be dlopen()ed, e.g. libgs_plugin_flatpak-user.so
>>>           has DT_NEEDED on:
>>>             - libflatpak0
>>
>> I don't think this is pedantical at all, it's IMO the only sane and
>> correct way to handle this.
> 
> Right, this way also allows the static linker to do its job and fix
> the symbol version.