使用$ORIGIN指定ELF二进制文件中的解释器无法工作

9

我正在使用patchelf来修改已编译二进制文件的rpath和解释器。调用patchelf的代码如下:

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

这些被正确设置了,可以通过运行 readelf -l ./grep | grep interpreter 进行验证,输出结果如下:

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

然而,当我尝试运行可执行文件时,出现以下错误:

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

这似乎表明链接器出现了问题。如果我使用绝对路径而不是使用 $ORIGIN,那么它似乎可以正常工作。

我想知道我在这里是否使用 $ORIGIN 的方式有些不正确,或者这可能是系统级别上已被禁用的某些东西吗?

1个回答

12

如果我指定绝对路径而不是使用 $ORIGIN,那么它似乎可以正常工作。

这正如预期的那样运作。

动态链接器解释(扩展)$ORIGIN和其他特殊标记。

Linux内核没有这样做。

而且是内核读取主可执行文件的PT_INTERP段,(如果存在)加载并调用解释器(动态链接器)。当您将解释器设置为不存在的路径(例如$ORIGIN/lib/ld-linux-x86-64.so.2)时,您将从内核execve系统调用中得到ENOENT

无法使解释器本身成为任何有效路径以外的东西。

根据您实际尝试实现的内容,rtldi可能是答案。


1
关于使用 $ORIGINPT_INTERP 中的安全漏洞,您对这篇文章的看法如何:https://backtrace.io/blog/exploiting-elf-expansion-variables/?这可能是不同内核版本之间存在差异的问题吗? - Ivanna
1
@Ivanna 那是特定于 Solaris 内核的。我更新了答案以反映 Linux 内核不会这样做。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接