将$ ORIGIN与setuid应用程序一起使用不会按预期失败

Ami*_*hum 15 c++ setuid shared-libraries clang++

我有一个librandom.so库和一个mainexectuable,编译如下:

$ clang++ -o main main.o -lrandom -L. -Wl,-rpath,"\$ORIGIN"
Run Code Online (Sandbox Code Playgroud)

它们都在同一目录中.由于main$ORIGIN在其中rpath,它工作正常 - ./main返回没有错误.

现在,我设置main与运行setuidroot:

$ sudo chown root main
$ sudo chmod a+s main
$ ./main
Run Code Online (Sandbox Code Playgroud)

我预计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
Run Code Online (Sandbox Code Playgroud)

当我main从包含目录运行时为什么它可以工作?

yug*_*ugr 6

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

$ORIGIN即使对于suid二进制文件,Glibc也有很长的扩展历史(参见例如CVE-2010-3847).这背后的动机是$ORIGIN用于rpath的suid二进制文件被设计破坏,因此Glibc开发人员从来没有打算解决这个问题.一些下游发行版在Glibc库存上提供补丁,禁用ORIGIN扩展,因此确切的情况取决于您的发行版.

有趣的是,只有独立$ORIGIN才能扩大 - 如果你用它取而代之,$ORIGIN/libs它将开始失败.

当我从包含目录运行main时,为什么它可以工作?

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