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?

xealits
  • 2,093
  • 3
  • 19
  • 27

1 Answers1

1

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.

zeppelin
  • 3,782
  • 10
  • 21
  • 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](https://github.com/calebmadrigal/static-shared-lib.git) 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 http://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