Gentoo Archives: gentoo-dev

From: "Robin H. Johnson" <robbat2@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] libtool lt_dlopenext vs. gen_ld_script: breakages at runtime
Date: Sun, 05 Jan 2014 04:09:20
gen_ld_script is removing a vital unversioned symlink from some packages, and
this breaks libtool lt_dlopenext consumers at runtime.

While examining bug #486640, I discovered a concerning interaction [1] between
libtool's lt_dlopenext and gen_ld_script.

I don't have a good handle on how many packages are affected, but it would be
an code that uses lt_dlopenext to try and find a library.

For our example, we're using the fact that sys-power/nut wants to use libusb
from dev-libs/libusb-compat.

dev-libs/libusb-compat has these files:
/usr/lib64/  (from gen_ld_script)
/lib64/ (symlink to 4.4.4)

lt_dlopenext is given the basename of a library to find. In this case, the
(modified) code tries both libusb and libusb-0.1, with slightly different failures:

1. lt_dlopenext cannot parse linker scripts at all, so the from
   gen_ld_script cannot be opened.
2. lt_dlopenext only tries to append .so, it doesn't add version specifiers.

If I manually add a symlink:
/lib64/ -> /lib64/
then lt_dlopenext succeeds.

This led me to looking at the libusb-compat in more detail.
Before gen_ld_script runs, it has the library and two symlinks in /usr/lib64:
/usr/lib64/ (symlink)
/usr/lib64/ (symlink)
At this stage, lt_dlopenext works still.

Now after gen_ld_script, the unversioned symlink is replaced by a linker
script. The versioned symlink and base file have moved to /lib64.

Since lt_dlopenext cannot handle the linker script, and the unversioned symlink
is gone, we now get a failure.

Proposed Fix:
I would like to propose that gen_ld_script does NOT remove the unversioned
symlinks, but instead moves them along with the versioned symlinks.

How can we sanely get all user systems updated for this subtle bug?

In bug #4411, comment 43, vapier noted:
> any package that does dlopen("") without the version info like ".so.X" is broken.
In this case, the lt_dlopenext consumer is explicitly testing multiple versions of libusb at runtime, and picking the correct interface: it doesn't need to depend on a specific version. This is also because the lt_dlopenext interface does NOT accepted files versioned after the .so: it needs the filename with no extensions. [1] I do half-expect vapier, flameeyes or patrick to shoot me down, and tell me the package is doing something wrong, but I've also got a chance of this actually being a system breakage. -- Robin Hugh Johnson Gentoo Linux: Developer, Infrastructure Lead E-Mail : robbat2@g.o GnuPG FP : 11ACBA4F 4778E3F6 E4EDF38E B27B944E 34884E85