1

I am testing how dynamic linking works with RUNPATH variable, and trying to run bash in a minimal chroot directory:

$ find dir_chroot/ -type f
dir_chroot/bin/bash
dir_chroot/lib/x86_64-linux-gnu/libc.so.6
dir_chroot/lib/x86_64-linux-gnu/libdl.so.2
dir_chroot/lib/x86_64-linux-gnu/libtinfo.so.5
dir_chroot/lib64/ld-linux-x86-64.so.2

-- these are all dependencies of bash, and they are actual binaries (find -type f), not symbolic links. Also they don't have RUNPATH:

$ find dir_chroot/ -type f -exec sh -c "readelf -d {} | grep RUNPATH" \;
$ 

chroot works fine with this directory:

$ sudo chroot dir_chroot /bin/bash
bash-4.3# exit
exit

However, if I copy everything and set RUNPATH to $ORIGIN/ in lib64/ld-linux-x86-64.so.2 I get exit code 139 (segfault?) when running chroot:

$ cp -R dir_chroot dir_chroot4
$ find dir_chroot4/ -type f -exec sh -c "echo {} `readelf -d {} | grep RUNPATH`" \; 
dir_chroot4/bin/bash
dir_chroot4/lib/x86_64-linux-gnu/libc.so.6
dir_chroot4/lib/x86_64-linux-gnu/libdl.so.2
dir_chroot4/lib/x86_64-linux-gnu/libtinfo.so.5
dir_chroot4/lib64/ld-linux-x86-64.so.2
$
$ patchelf --set-rpath "\$ORIGIN/" dir_chroot4/lib64/ld-linux-x86-64.so.2
$ find dir_chroot4/ -type f -exec sh -c "echo {} `readelf -d {} | grep RUNPATH`" \; 
dir_chroot4/bin/bash
dir_chroot4/lib/x86_64-linux-gnu/libc.so.6
dir_chroot4/lib/x86_64-linux-gnu/libdl.so.2
dir_chroot4/lib/x86_64-linux-gnu/libtinfo.so.5
dir_chroot4/lib64/ld-linux-x86-64.so.2 0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/]
$
$ sudo chroot dir_chroot4 /bin/bash
$
$ echo $status
139

-- $status is the status variable in fish shell.

It happens only if ld-linux-x86-64.so.2 is patched, other libraries and bash executable work ok with RUNPATH. Why is it so?

1
+50

Apparently, ld-linux-x86-64.so.2 is statically linked, at least it is on my system:

>ldd ld-linux-x86-64.so.2
statically linked

unlike libc.so.6,libdl.so.2 and libtinfo.so.5

>ldd libc.so.6 libdl.so.2 libtinfo.so.5

libc.so.6:
/lib64/ld-linux-x86-64.so.2 (0x000056469847a000)
linux-vdso.so.1 =>  (0x00007ffe95185000)

libdl.so.2:
linux-vdso.so.1 =>  (0x00007fffc4718000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa1df136000)
/lib64/ld-linux-x86-64.so.2 (0x0000558334a9c000)

libtinfo.so.5:
linux-vdso.so.1 =>  (0x00007ffe1b7bd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffa990b9000)
/lib64/ld-linux-x86-64.so.2 (0x00005590bfced000)

which makes the loader go mad and results in a segfault, when you forcibly inject RUNPATH into it.

  • yep, apparently it is so. If you know how to link a shared/dynamic library statically, could you add it to the answer for testing purposes? When I statically link an executable it doesn't have a dynamic section -- nowhere to add a RUNPATH. Also this test on github doesn't work for me, breaks with: relocation R_X86_64_32 against __TMC_END__ can not be used when making a shared object; recompile with -fPIC – xealits Nov 16 '16 at 16:24
  • > If you know how to link a shared/dynamic library statically, could you add it to the answer for testing purposes? Well, not sure I will be able to help you with this. You can probably give a try to some tool like Statifier statifier.sourceforge.net, but AFAIK they all are rather hackish and can break things. So, I would probably just recompile the library in question from sources instead. BTW I guess this would make a nice question on its own ! – zeppelin Nov 17 '16 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.