Bug 24260 - ldd does not find dependent libraries through rpath entries that use $ORIGIN
Summary: ldd does not find dependent libraries through rpath entries that use $ORIGIN
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: hurd (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-02-23 19:01 UTC by Bruno Haible
Modified: 2019-04-02 15:57 UTC (History)
2 users (show)

See Also:
Host: i686-unknown-gnu0.9
Target:
Build:
Last reconfirmed: 2019-02-23 00:00:00
fweimer: security-


Attachments
Test case (92 bytes, text/plain)
2019-02-23 19:02 UTC, Bruno Haible
Details
Test case (40 bytes, text/plain)
2019-02-23 19:02 UTC, Bruno Haible
Details
Test case (253 bytes, application/gzip)
2019-02-23 19:04 UTC, Bruno Haible
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bruno Haible 2019-02-23 19:01:19 UTC
On Hurd, 'ldd' from glibc does not find the dependent libraries when their lookup requires rpath entries that use $ORIGIN. On Linux, in contrast, this works.

How to reproduce:
Take main.c and lib.c from the attachments.

On Hurd:
$ gcc -Wall -shared -o libfoo.so lib.c
$ mkdir inst1
$ gcc -Wall -o inst1/main main.c libfoo.so '-Wl,-rpath,$ORIGIN'
$ mv libfoo.so inst1/libfoo.so
$ inst1/main
bar -> 42
$ ldd inst1/main
        libfoo.so => not found
        libc.so.0.3 => /lib/i386-gnu/libc.so.0.3 (0x01012000)
        /lib/ld.so => /lib/ld.so.1 (0x08000000)
        libmachuser.so.1 => /lib/i386-gnu/libmachuser.so.1 (0x01258000)
        libhurduser.so.0.3 => /lib/i386-gnu/libhurduser.so.0.3 (0x01271000)
$ mv inst1 inst2
$ inst2/main
bar -> 42
$ ldd inst2/main
        libfoo.so => not found
        libc.so.0.3 => /lib/i386-gnu/libc.so.0.3 (0x01012000)
        /lib/ld.so => /lib/ld.so.1 (0x08000000)
        libmachuser.so.1 => /lib/i386-gnu/libmachuser.so.1 (0x01258000)
        libhurduser.so.0.3 => /lib/i386-gnu/libhurduser.so.0.3 (0x01271000)
$ ldd --version
ldd (Debian GLIBC 2.28-7) 2.28
...
$ readelf -d inst2/main
...
0x0000001d (RUNPATH)                          Library runpath: [$ORIGIN]
...

For comparison, on Linux (good results):
$ gcc -Wall -shared -o libfoo.so lib.c
$ mkdir inst1
$ gcc -Wall -o inst1/main main.c libfoo.so '-Wl,-rpath,$ORIGIN'
$ mv libfoo.so inst1/libfoo.so
$ inst1/main
bar -> 42
$ ldd inst1/main
        linux-vdso.so.1 =>  (0x00007ffc75f32000)
        libfoo.so => /devel/ldd-bug/inst1/libfoo.so (0x00007f8c5357c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c531b2000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8c5377e000)
$ mv inst1 inst2
$ inst2/main
bar -> 42
$ ldd inst2/main
        linux-vdso.so.1 =>  (0x00007fffcfb7d000)
        libfoo.so => /devel/ldd-bug/inst2/libfoo.so (0x00007f9ffbf2e000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9ffbb64000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9ffc130000)
Comment 1 Bruno Haible 2019-02-23 19:02:05 UTC
Created attachment 11639 [details]
Test case
Comment 2 Bruno Haible 2019-02-23 19:02:41 UTC
Created attachment 11640 [details]
Test case
Comment 3 Bruno Haible 2019-02-23 19:04:49 UTC
Created attachment 11641 [details]
Test case

Test case as a tar.gz file.
Comment 4 Samuel Thibault 2019-02-23 20:03:08 UTC
Mmm...

What normally happens is you run the program, and the exec server sets the LD_ORIGIN_PATH environment variable for the dynamic linker to find it for $ORIGIN substitution (see exec/exec.c's do_exec).

But here it's ld.so which loads the binary, so the variable wouldn't be set. Perhaps we need to make ld.so itself set LD_ORIGIN_PATH in that case.