Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $ORIGIN to specify the interpreter in ELF binaries isn't working

Tags:

linux

linker

elf

I'm using patchelf to modify rpath and the interpreter for already compiled binaries. The calls to patchelf look something like this:

patchelf --set-interpreter "\$ORIGIN/lib/ld-linux-x86-64.so.2" --set-rpath "\$ORIGIN/lib" ./grep

These are being set correctly, as verified by running readelf -l ./grep | grep interpreter, which outputs:

[Requesting program interpreter: $ORIGIN/lib/ld-linux-x86-64.so.2]

When I try to run the executable, however, I get the following error:

-bash: ./grep: No such file or directory

This seems to indicate that there's an issue with the linker. If I specify an absolute path instead of using $ORIGIN then it seems to work fine.

I'm wondering if there's something incorrect about how I'm using $ORIGIN here, or if this is perhaps something that has perhaps been disabled on a system level?

like image 957
Ivanna Avatar asked Jan 25 '18 22:01

Ivanna


1 Answers

If I specify an absolute path instead of using $ORIGIN then it seems to work fine.

This is working as intended.

It is the dynamic linker that interprets (expands) $ORIGIN and other special tokens.

The Linux kernel doesn't.

And it is the kernel that reads PT_INTERP segment of the main executable and (if present) loads and invokes the interpreter (the dynamic linker). When you set interpreter to non-existant path (such as $ORIGIN/lib/ld-linux-x86-64.so.2), you get ENOENT from the kernel execve system call.

There is no way to make interpreter itself be anything other than valid path.

Depending on what you are actually trying to achieve, rtldi may be the answer.

like image 166
Employed Russian Avatar answered Oct 18 '22 04:10

Employed Russian