1 |
Summary: |
2 |
-------- |
3 |
gen_ld_script is removing a vital unversioned symlink from some packages, and |
4 |
this breaks libtool lt_dlopenext consumers at runtime. |
5 |
|
6 |
Details: |
7 |
-------- |
8 |
While examining bug #486640, I discovered a concerning interaction [1] between |
9 |
libtool's lt_dlopenext and gen_ld_script. |
10 |
|
11 |
I don't have a good handle on how many packages are affected, but it would be |
12 |
an code that uses lt_dlopenext to try and find a library. |
13 |
|
14 |
For our example, we're using the fact that sys-power/nut wants to use libusb |
15 |
from dev-libs/libusb-compat. |
16 |
|
17 |
dev-libs/libusb-compat has these files: |
18 |
/usr/lib64/libusb.so (from gen_ld_script) |
19 |
/lib64/libusb-0.1.so.4.4.4 |
20 |
/lib64/libusb-0.1.so.4 (symlink to 4.4.4) |
21 |
|
22 |
lt_dlopenext is given the basename of a library to find. In this case, the |
23 |
(modified) code tries both libusb and libusb-0.1, with slightly different failures: |
24 |
|
25 |
1. lt_dlopenext cannot parse linker scripts at all, so the libusb.so from |
26 |
gen_ld_script cannot be opened. |
27 |
2. lt_dlopenext only tries to append .so, it doesn't add version specifiers. |
28 |
|
29 |
If I manually add a symlink: |
30 |
/lib64/libusb-0.1.so -> /lib64/libusb-0.1.so.4 |
31 |
then lt_dlopenext succeeds. |
32 |
|
33 |
This led me to looking at the libusb-compat in more detail. |
34 |
Before gen_ld_script runs, it has the library and two symlinks in /usr/lib64: |
35 |
/usr/lib64/libusb-0.1.so.4.4.4 |
36 |
/usr/lib64/libusb-0.1.so.4 (symlink) |
37 |
/usr/lib64/libusb.so (symlink) |
38 |
At this stage, lt_dlopenext works still. |
39 |
|
40 |
Now after gen_ld_script, the unversioned symlink is replaced by a linker |
41 |
script. The versioned symlink and base file have moved to /lib64. |
42 |
|
43 |
Since lt_dlopenext cannot handle the linker script, and the unversioned symlink |
44 |
is gone, we now get a failure. |
45 |
|
46 |
Proposed Fix: |
47 |
------------- |
48 |
I would like to propose that gen_ld_script does NOT remove the unversioned |
49 |
symlinks, but instead moves them along with the versioned symlinks. |
50 |
|
51 |
Questions: |
52 |
---------- |
53 |
How can we sanely get all user systems updated for this subtle bug? |
54 |
|
55 |
Comments: |
56 |
--------- |
57 |
In bug #4411, comment 43, vapier noted: |
58 |
> any package that does dlopen("libfoo.so") without the version info like ".so.X" is broken. |
59 |
In this case, the lt_dlopenext consumer is explicitly testing multiple versions |
60 |
of libusb at runtime, and picking the correct interface: it doesn't need to |
61 |
depend on a specific version. This is also because the lt_dlopenext interface |
62 |
does NOT accepted files versioned after the .so: it needs the filename with no |
63 |
extensions. |
64 |
|
65 |
[1] I do half-expect vapier, flameeyes or patrick to shoot me down, and tell me |
66 |
the package is doing something wrong, but I've also got a chance of this |
67 |
actually being a system breakage. |
68 |
|
69 |
-- |
70 |
Robin Hugh Johnson |
71 |
Gentoo Linux: Developer, Infrastructure Lead |
72 |
E-Mail : robbat2@g.o |
73 |
GnuPG FP : 11ACBA4F 4778E3F6 E4EDF38E B27B944E 34884E85 |