如何从root用户使用setuid()成为用户,以后可能再次成为root用户?

时间:2010-02-16 18:21:35

标签: c linux security root setuid

我正在尝试做安全的事情,并且有一个程序需要以root用户身份运行,以便在不需要时删除其权限。如果我chmod我的二进制文件与SUID位,并使其属于root,这很好用,因为现在我有UID =某个用户,EUID = root,所以我可以使用seteuid(0)和{{ 1}}分别提升和放弃管理员权限。

但是如果我使用seteuid(getuid())而不是设置SUID,那么UID == EUID == 0,因此调用sudo将不会产生任何影响。而且我不能只将seteuid(getuid())更改为某个随机用户的某个值,因为UID手册页明确指出如果从以root身份运行的程序调用它,则会丢失权限,没有希望让他们回来。

那么,在使用setuid()

运行时,如何让我的程序暂时失去其权限?

4 个答案:

答案 0 :(得分:10)

seteuid(some random uid)seteuid(0)运行时,删除权限root以取回权限。

答案 1 :(得分:6)

似乎seteuid(x)应该努力放弃并重新提升私人......

$ cat > t12.c
#include <stdio.h>
#include <unistd.h>

void p(void) { printf("euid=%4d uid=%4d\n", geteuid(), getuid()); }

int main(void) { p(); seteuid(100); p(); seteuid(0); p(); return 0; }
$ cc -Wall t12.c
$ sudo chown root a.out && sudo chmod 4555 a.out
$ sudo ./a.out
euid=   0 uid=   0
euid= 100 uid=   0
euid=   0 uid=   0
$ ./a.out
euid=   0 uid= 501
euid= 100 uid= 501
euid=   0 uid= 501
$ 

答案 2 :(得分:3)

不是直接回答,只是想指出privilege separation的想法。这是OpenBSD创始人Theo de Raadt的一个伟大的presentation

答案 3 :(得分:1)

删除权限之前

Fork()。等待父任务,直到完成权限降低的子进程,然后在具有root的父进程中继续。

seteuid不适用于所有unices,也有其他缺点。