二进制文件上的 SUID 位仍然产生“权限被拒绝”错误

JTJ*_*TJM 6 ubuntu permissions

alice并且bob都属于该staff组。

我有以下文件夹:

drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share

文件夹内有以下文件:

-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt
Run Code Online (Sandbox Code Playgroud)

display-foo是一个二进制文件,主要显示foo.txt使用cat命令的内容。

alice运行./display-foo,成功的二进制文件和执行的内容 foo.txt被显示。但是,当bob运行./display-foo,成功的二进制文件,但执行的内容foo.txt不显示的,产生的误差/bin/cat: /home/alice/share/foo.txt: Permission denied


根据我的理解,设置 setuid 位允许使用文件所有者(在本例中为alice)的权限执行二进制可执行文件。那么,为什么bob不允许查看 的内容foo.txt


附录:我已经用该函数重新编译了我的二进制文件,geteuid()以便它打印出有效的用户 ID (EUID)。实际上,当bob执行二进制文件时,EUID 是alice. 然而,许可被拒绝。这是源代码的一个片段:

printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");
Run Code Online (Sandbox Code Playgroud)

iga*_*gal 3

我通读了该函数的手册页system,发现了以下段落,其中提供了解释:

\n\n
\n
Do not use system() from a program with set-user-ID or set-group-ID\nprivileges, because strange values for some environment variables\nmight be used to subvert system integrity.  Use the exec(3) family of\nfunctions instead, but not execlp(3) or execvp(3).  system() will\nnot, in fact, work properly from programs with set-user-ID or set-\ngroup-ID privileges on systems on which /bin/sh is bash version 2,\nsince bash 2 drops privileges on startup.  (Debian uses a modified\nbash which does not do this when invoked as sh.)\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

以下是我在阅读该段落时阅读的其他一些 StackExchange 帖子:

\n\n\n\n

对于后代,并且因为给定的示例可能有助于在其他情况下诊断此问题或类似问题,所以我在下面保留了原始示例。

\n\n
\n\n

您是否可能遇到了错误?我无法在运行 Debian 9 和 gcc 6.3 的 Docker 容器中重现您的问题。以下是我如何尝试重新创建您帖子中描述的场景。

\n\n

首先创建“alice”和“bob”用户并将他们添加到“staff”组:

\n\n
Do not use system() from a program with set-user-ID or set-group-ID\nprivileges, because strange values for some environment variables\nmight be used to subvert system integrity.  Use the exec(3) family of\nfunctions instead, but not execlp(3) or execvp(3).  system() will\nnot, in fact, work properly from programs with set-user-ID or set-\ngroup-ID privileges on systems on which /bin/sh is bash version 2,\nsince bash 2 drops privileges on startup.  (Debian uses a modified\nbash which does not do this when invoked as sh.)\n
Run Code Online (Sandbox Code Playgroud)\n\n

接下来创建文件并设置其所有权和权限:

\n\n
useradd -m -G staff alice\nuseradd -m -G staff bob\n
Run Code Online (Sandbox Code Playgroud)\n\n

让我们检查一下结果:

\n\n
$ ls -l /home/alice/share/foo.txt\n-rw------- 1 alice alice 16 Nov  4 15:33 /home/alice/share/foo.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在让我们创建一个display-foo使用该system函数的版本:

\n\n
$ cat <<HEREDOC > /usr/local/src/display-foo.c\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <pwd.h>\n\nint main(int argc, char **argv) {\n\n    struct passwd *r_pwd = getpwuid(getuid());\n    printf("Real user: %s\\n", r_pwd->pw_name);\n\n    struct passwd *e_pwd = getpwuid(geteuid());\n    printf("Effective user: %s\\n", e_pwd->pw_name);\n\n    system("/bin/cat /home/alice/share/foo.txt");\n}\nHEREDOC\n\n$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo\n
Run Code Online (Sandbox Code Playgroud)\n\n

让我们设置 的所有权和权限display-foo,包括设置 setuid 位:

\n\n
# Create a subdirectory to hold the text file\nsudo -u alice mkdir -p /home/alice/share/\n\n# Create the text file\nsudo -u alice bash -c \'echo "This is foo.txt" > /home/alice/share/foo.txt\'\n\n# Set restrictive permissions on the text file\nchmod u=rw,g=,o= /home/alice/share/foo.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

我们还检查一下结果:

\n\n
$ ls -l /usr/local/bin/display-foo\n-rwsr-xr-x 1 alice alice 8640 Nov  4 15:40 /usr/local/bin/display-foo\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我们运行程序 asalice和 as bob

\n\n
$ ls -l /home/alice/share/foo.txt\n-rw------- 1 alice alice 16 Nov  4 15:33 /home/alice/share/foo.txt\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,看起来一切都按预期进行。

\n