Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $ORIGIN with setuid application does not fail as expected

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?

like image 652
Amir Rachum Avatar asked Sep 14 '16 09:09

Amir Rachum


1 Answers

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.

like image 177
yugr Avatar answered Oct 24 '22 01:10

yugr