所以我有这个简单的 C 程序:
#include<stdio.h>
int main(){
printf("\nreal uid: %d\n", getuid());
printf("\neffective uid: %d\n", geteuid());
}
我编译它:
user@user:~/Desktop$ gcc -o uid_demo uid_demo.c
我查看了权限:
user@user:~/Desktop$ ls -l uid_demo
-rwxr-xr-x 1 user user 8512 set 17 11:30 uid_demo
并运行它:
user@user:~/Desktop$ ./uid_demo
real uid: 1000
effective uid: 1000
一切都好,我继续说:
user@user:~/Desktop$ sudo chown root:root uid_demo
user@user:~/Desktop$ ls -l uid_demo
-rwxr-xr-x 1 root root 8512 set 17 11:30 uid_demo
和
user@user:~/Desktop$ sudo chmod u+s uid_demo
user@user:~/Desktop$ ls -l uid_demo
-rwsr-xr-x 1 root root 8512 set 17 11:30 uid_demo
问题来了:
user@user:~/Desktop$ ./uid_demo
real uid: 1000
effective uid: 1000
我期待看到 真实 uid: 1000和有效 uid: 0
我错过了什么?
啊,当然了:
user@user:~/Desktop$ id user
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),121(lpadmin),131(sambashare)
答案1
这可能nosuid
是在可执行文件所在的文件系统上设置挂载选项的结果。为了说明,给定
$ cat uid_demo.c
#include<stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
printf("\nreal uid: %d\n", getuid());
printf("\neffective uid: %d\n", geteuid());
}
然后
$ gcc -o uid_demo uid_demo.c
$ sudo chown root:root uid_demo
$ sudo chmod u+s uid_demo
$ ls -l uid_demo
-rwsrwxr-x 1 root root 8512 Sep 17 07:53 uid_demo
$
$ ./uid_demo
real uid: 1000
effective uid: 0
按预期工作;但是当重新安装时nosuid
,该suid
位仍然存在,但被忽略:
$ sudo mount -o remount,nosuid /home
$ ls -l uid_demo
-rwsrwxr-x 1 root root 8512 Sep 17 07:53 uid_demo
$
$ ./uid_demo
real uid: 1000
effective uid: 1000
如果你知道文件所在的挂载点,你可以通过 grep 命令的输出来查看其文件系统挂载选项,mount
例如
$ mount | grep /home
/dev/sda6 on /home type ext4 (rw,nosuid,relatime,data=ordered)
答案2
正如您在 Unix.SE 问答中所看到的setuid 位似乎对 bash 没有影响
bash 检测到它已以 SUID root (UID!=EUID) 身份启动,并使用其 root 权限放弃此权限,将 EUID 重置为 UID
更多详情链接的答案