The combination of set-uid and relative path in the INTERP section of the ELF binary is very dangerous.
I'm not quite sure how and where this issue should be reported, but it seems to me that the general security issue is related to how dynamic linking in linux / glibc works, so let me explain what it is:
Consider creating a dynamically linked binary and specifying a relative path in the ELF INTERP section (using the -dynamic-linker gcc option) so that you can distribute a custom version of glibc with your dynamically linked commercial application (where you are not allowed to statically link to LGPL glibc but still you need to do your binary work on different Linux distributions having different versions of glibc).
If you use the root binary and put the set-uid flag in your binary, it will become a rootkit. By executing it from another directory, you can replace the dynamic linker executable file, which will be executed with root privileges.
To demonstrate this, take a look at the following C code (issue.c):
#include <stdio.h> // // build with: // gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c // sudo chown root issue // sudo chmod u+s issue // now build some code to be executed with root permissions (we use the same issue.c): // mkdir -p .lib64/ // gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c // int main(int argc, char* argv[]) { printf("(%s) euid:%d\n", NAME, geteuid()); }
If you are currently executing the set-uid binary, like this
./issue
or even just do it
ldd issue
instead of getting what you expect, for example:
(vulnarable) euid:0
You are getting:
(rootkit) euid:0
Now you can replace the ld-linux-x86-64.so.6 binary with whatever you like.
Similar issues seem to have been fixed by not allowing $ ORIGIN in RPATH or ignoring LD_LIBRARY_PATH if the set-uid flag is set.
So I wonder if I should ignore INTERP in ELF when the set-uid flag is set (i.e. using the default dynamic linker - / lib32 / ld-linux.so.2 or / lib 64 / ld-linux -x86-64 .so.2)?
So, where do you think this should be fixed or reported - in glibc or the kernel?