【问题标题】:Using $ORIGIN with setuid application does not fail as expected将 $ORIGIN 与 setuid 应用程序一起使用不会按预期失败
【发布时间】:2017-01-22 01:10:24
【问题描述】:

我有一个librandom.so 库和一个main 可执行文件,编译如下:

$ clang++ -o main main.o -lrandom -L. -Wl,-rpath,"\$ORIGIN"

它们都在同一个目录中。因为main 在其rpath 中有$ORIGIN,所以它工作正常 - ./main 返回没有错误。

现在,我将main 设置为与setuid 一起作为root 运行:

$ sudo chown root main
$ sudo chmod a+s main
$ ./main

我预计main 会失败,因为$ORIGIN 没有在setuid 应用程序中扩展。令人惊讶的是,它有效。

但是,如果我从另一个目录运行 main,它确实会按预期失败:

$ 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

为什么当我从其包含目录运行main 时它会起作用?

【问题讨论】:

    标签: c++ shared-libraries clang++ setuid


    【解决方案1】:

    我预计 main 会失败,因为 $ORIGIN 未在 setuid 应用程序中扩展。 令人惊讶的是,它有效。

    Glibc 有很长的扩展 $ORIGIN 的历史,即使是 suid 二进制文件(参见例如 CVE-2010-3847)。这背后的动机是使用$ORIGIN rpath 的suid 二进制文件被设计破坏了,因此Glibc 开发人员从不费心去修复这个问题。一些下游发行版在库存 Glibc 之上提供了补丁,这些补丁禁用了 ORIGIN 扩展,因此具体情况取决于您的发行版。

    很有趣,只有独立的 $ORIGIN 会被扩展 - 如果你用例如替换它$ORIGIN/libs 它会开始失败。

    为什么当我从包含目录运行 main 时它会起作用?

    移动文件后,$ORIGIN 将扩展至不再包含所需库的不同文件夹。

    【讨论】:

    • 关于第二部分 - 我没有移动文件,只是移动当前目录。 $ORIGIN 是相对于可执行文件的位置,而不是当前工作目录。
    • 对。似乎 Ubuntu 使用了 Glibc 补丁的变体,它将 $ORIGIN 扩展为空字符串(例如,在 this comment 中描述)。然后,动态链接器会将其视为可以解释行为的 CWD。您可能可以report this to developers,但我怀疑他们会感兴趣。
    猜你喜欢
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    相关资源
    最近更新 更多