用户 ID,C 程序

用户 ID,C 程序

所以我有这个简单的 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

更多详情链接的答案

相关内容