This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug dynamic-link/14761] New: Compatibility symlink from old dynamic loader name to new dynamic loader name doesn't work.
- From: "carlos_odonell at mentor dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: Wed, 24 Oct 2012 14:26:14 +0000
- Subject: [Bug dynamic-link/14761] New: Compatibility symlink from old dynamic loader name to new dynamic loader name doesn't work.
- Auto-submitted: auto-generated
http://sourceware.org/bugzilla/show_bug.cgi?id=14761
Bug #: 14761
Summary: Compatibility symlink from old dynamic loader name to
new dynamic loader name doesn't work.
Product: glibc
Version: 2.17
Status: NEW
Severity: normal
Priority: P2
Component: dynamic-link
AssignedTo: unassigned@sourceware.org
ReportedBy: carlos_odonell@mentor.com
Classification: Unclassified
The ARM GNU/Linux hard-float ABI linker name changed recently.
It was changed from /lib/ld-linux.so.3 to /lib/ld-linux-armhf.so.3.
It seemed pretty obvious that a simple way to provide backwards
compatibility for old applications was to create a symlink from
ld-linux.so.3 to ld-linux-armhf.so.3, but this turns out to be
harder than you would think.
On April 18th Steve McIntyre posts this patch:
http://sourceware.org/ml/libc-ports/2012-04/msg00081.html
The patch is designed to prevent the initial dynamic loader from
loading itself twice. It turns out that the symlink confuses the
code in elf/dl-load.c (_dl_map_object) and it does not correctly
determine that both dynamic linkers are the same (symlink really).
Without the patch there are two copies of the dynamic linker loaded.
The first is ld-linux-armhf.so.3 in the initial scope 0 of the application as
is ld-linux-armhf.so.3:
~~~
722: Initial object scopes
722: object=./test [0]
722: scope 0: ./test
/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib/libdl.so.2
/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib/libgcc_s.so.1
/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib/libc.so.6
/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib/ld-linux-armhf.so.3
~~~
The second is created by a forcible DT_NEEDED entry in a legacy
shared library. Something which shouldn't happen, but is technically
possible and not disallowed. You get this kind of thing for example
if you listed /lib/ld-linux.so.3 as an object on the link line
while building the legacy shared library with a legacy toolchain.
Some applications build like this and we need to support it or at
the very least not crash the application.
For example in ./libtest.so:
~~~
...
Dynamic section at offset 0x590 contains 27 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [ld-linux.so.3]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000e (SONAME) Library soname: [libtest.so]
...
~~~
Continuing the same trace, when we process libtest.so we load ld-linux.so.3
(which is just a symlink to ld-linux-armhf.so.3):
~~~
722: file=ld-linux.so.3 [0]; needed by ./libtest.so [0]
722: find library=ld-linux.so.3 [0]; searching
722: search
path=/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/v7l/neon/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/v7l/neon:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/v7l/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/v7l:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/neon/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/neon:/scratch/carloso/build4-l
ucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/tls:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/v7l/neon/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/v7l/neon:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/v7l/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/v7l:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/neon/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gn
ueabi/libc/armv7-a-hard/usr/lib/neon:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib/vfp:/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/usr/lib:./tls/v7l/neon/vfp:./tls/v7l/neon:./tls/v7l/vfp:./tls/v7l:./tls/neon/vfp:./tls/neon:./tls/vfp:./tls:./v7l/neon/vfp:./v7l/neon:./v7l/vfp:./v7l:./neon/vfp:./neon:./vfp:.
(LD_LIBRARY_PATH)
722: trying
file=/scratch/carloso/build4-lucid-cs/arm-none-linux-gnueabi-sourceryg++/install/arm-none-linux-gnueabi/libc/armv7-a-hard/lib/ld-linux.so.3
722:
722: file=ld-linux.so.3 [0]; generating link map
722: dynamic: 0x401b7f44 base: 0x4018e000 size: 0x0002a96c
722: entry: 0x4018ee40 phdr: 0x4018e034 phnum: 6
~~~
Either way the question is: Does it cause any real problems to have two
copies of the dynamic loader loaded?
Adam Conrad thankfully provided me with a trace of cc1 crashing with
a dynamic linker that isn't patched:
http://paste.ubuntu.com/1261263/
>From the above trace the following jumps out at me:
~~~
16727: binding file /lib/ld-linux-armhf.so.3 [0] to
/lib/arm-linux-gnueabihf/ld-linux.so.3 [0]: normal symbol `__tls_get_addr'
[GLIBC_2.4]
~~~
This looks wrong and problematic. Perhaps a minimal test case can
be constructed with TLS that shows the crash.
There are also vague comments in elf/dl-load.c (_dl_map_object_from_fd)
that say:
~~~
/* When loading into a namespace other than the base one we must
avoid loading ld.so since there can only be one copy. Ever. */
~~~
Which again doesn't tell us why that would be the case.
Detecting that the two objects are identical in _dl_map_object_from_fd
would be the most optimal solution, but it would require refactoring
the loading code to map in and read DT_SONAME as early as possible and
abort the load if we detected an existing SONAME already loaded.
I don't think that walking the symlink to see if the two files match is not an
acceptable solution.
In summary:
- To support compatibility symlinks from old dynamic loader names to new
dynamic loader names will require refactoring _dl_map_object_from_fd to
actually detect if two DSOs are the same.
--
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.