I have a librandom.so
library and a main
exectuable which was compiled as follows:
$ clang++ -o main main.o -lrandom -L. -Wl,-rpath,"\$ORIGIN"
They are both in the same directory. Since main
has $ORIGIN
in its rpath
, it works fine - ./main
returns without errors.
Now, I'm setting main
to run with setuid
as root
:
$ sudo chown root main
$ sudo chmod a+s main
$ ./main
I expected main
to fail since $ORIGIN
is not expanded in setuid
applications. Surprisingly, it works.
If I run main
from another directory, though, it does fail as expected:
$ cd /tmp
$ /path/to/main
/path/to/main: error while loading shared libraries: librandom.so: cannot open shared object file: No such file or directory
Why does it work when I run main
from its containing directory?
I expected main to fail since $ORIGIN is not expanded in setuid applications. Surprisingly, it works.
Glibc has a long history of expanding $ORIGIN
even for suid binaries (see e.g. CVE-2010-3847). The motivation behind this is that suid binaries that use $ORIGIN
for rpath are broken by design so Glibc developers were never very bothered to fix this. Some downstream distros provided patches on top of stock Glibc which disable ORIGIN-expansion so exact situation depends on your distro.
Funny enough, only free-standing $ORIGIN
will be expanded - if you replace it with e.g. $ORIGIN/libs
it'll start to fail.
Why does it work when I run main from its containing directory?
Once you move your file, $ORIGIN
will expand to different folder which no longer contains the required library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With