为什么 setuid 不适用于可执行文件?

为什么 setuid 不适用于可执行文件?

我知道在脚本上启用 setuid 存在安全问题,因此默认情况下处于非活动状态,但希望它适用于可执行文件。我按照本文中描述的说明创建了一个可执行文件,它将 uid 显示为输出:允许在 shell 脚本上设置 setuid

但它在运行之前和之后返回相同的 uid (1000) sudo chmod +s ./setuid-test。我认为这意味着 setuid 对我的可执行文件没有任何影响,为什么以及如何解决?

源代码:

#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv) {
    printf("%d", geteuid());
    return 0;
}

构建并运行

$ gcc -o setuid-test setuid-test.c
$ ./setuid-test
1000
$ sudo chown nobody ./setuid-test; sudo chmod +s ./setuid-test
$ ./setuid-test
1000

运行时ls -la,这就是我得到的:

me@me:~$ ls -la setuid-test
-rwsrwsr-x 1 nobody me 8572 Aug 19 16:39 setuid-test

答案1

大多数为 Unix/Linux 设计的文件系统都可以使用nosuid属性进行挂载,这将防止位于这些文件系统上的 setuid 或 setgid 二进制文件更改进程的有效 uid 或 gid。它通常在安装“不受信任”的文件系统(即受非管理员控制的文件系统)时使用。

就你的情况而言,你使用的文件系统类型是 ecryptfs,根据askubuntu:在加密的主目录下使用 root setuid 运行二进制文件时出错从几年前的版本开始,自动强制执行nosuid(和nodev)。

以下是更改原因的描述,来自https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-3409:

Vincent Danen 2012-07-20 11:25:56 EDT
据报道,私有 ecryptfs 挂载助手(/sbin/mount.ecryptfs_private),即 setuid-root,可以允许非特权本地用户挂载用户控制的 ecryptfs 共享在本地系统上。由于 ecryptfs 帮助程序不会挂载带有“nosuid”和“nodev”标志的文件系统,因此用户可能会挂载包含 setuid-root 二进制文件和/或设备文件的文件系统,从而导致其权限升级。如果用户可以物理访问系统,则可以通过 USB 设备完成此操作。
...
版本 99 中添加了强制 MS_NOSUID 和 MS_NODEV 安装标志。

答案2

可执行文件上的 SetUID 位允许在文件中运行可执行文件所有者(不是超级用户)。为了能够以 root 身份运行可执行文件,请执行:

sudo chown 0:0 ./setuid-test

相关内容