我目前正在阅读一本关于使用 C 语言编程的书,其中有一部分内容是编写一个程序来显示文件正在执行的实际 uid 和有效 uid。使用 gcc 编译代码后,我输入命令来查看当前的 uOwner 和 gOwner,ls- l id_demo
输出如下
-rwxrwxr-x 1 user user 8629 Sep 21 13:04 id_demo
然后我执行程序本身,得到的结果如下:
real uid: 1000 effective uid: 1000
...到目前为止,一切都很好。
然后我输入一个命令来更改文件所有者sudo chown root:root ./id_demo
,确认ls -l
所有者已更改为 root;
-rwxrwxr-x 1 root root 8629 Sep 21 13:04 id_demo
再次执行程序显示real uid
和uid
为 1000。最后一步之后必须uid
为 0:sudo chmod u+s ./uid_demo
但对我来说它们保持为 1000,而在书中输出清楚地显示为:
real uid: 1000 effective uid: 0
知道为什么会发生这种情况吗?
更新
id_demo源代码:
#include <stdio.h>
int main ()
{
printf("real uid: %d\n", getuid());
printf("effective uid: %d\n", geteuid());
}
更新2 屏幕截图
答案1
您仅为 root 更改了 suid(u+s
当所有者是 root 时)。请执行chmod a+s ./uid_demo
。
在 OP 发布代码后进行编辑:对我有用。
xxxxx@xxxxx:~$ cat > test.c
#include <stdio.h>
int main ()
{
printf("real uid: %d\n", getuid());
printf("effective uid: %d\n", geteuid());
}
xxxxx@xxxxx:~$ gcc -o testuid test.c
xxxxx@xxxxx:~$ ./testuid
real uid: 1000
effective uid: 1000
xxxxx@xxxxx:~$ sudo chown root:root testuid
xxxxx@xxxxx:~$ sudo chmod a+s testuid
xxxxx@xxxxx:~$ ./testuid
real uid: 1000
effective uid: 0
xxxxx@xxxxx:~$ ls -l testuid
-rwsrwsr-x 1 root root 8625 Sep 21 14:45 testuid
您可以这样做:(i) 按照上面所示从头开始做所有事情。如果这不起作用,您可以尝试使用strace
以查看发生了什么。
答案2
我们已经找到答案了。原因是ecryptfs
-mounted 主目录。mount
输出包含以下行:
/home/evgeny/.Private on /home/evgeny type ecryptfs
这意味着主目录实际上不是根文件系统的一部分(具有必要的suid
标志),而是它自己的虚拟文件系统,默认情况下显然不支持 setuid 二进制文件。我已成功使用具有加密主目录的测试用户重现了该问题。
可以suid
使用以下命令将标志添加到 ecryptfs:
sudo mount -i -o remount,suid /home/evgeny
但我不确定这有多安全,也不知道如何永久地改变它以使其能够在重启后继续存在。