issetugid的目的?

时间:2013-05-18 02:23:36

标签: linux unix solaris setuid

根据issetugid的手册页,该调用应该是(1)警告uid / gid更改;或(2)警告可能受污染的环境。功能名称表明了第三个目的。

第一个问题:它的目的是什么?

当我查看可用的实现时(例如,在Linux系统上作为库,因为Linux内核不提供API),我发现以下内容:

if (getuid() != geteuid()) return 1; 
if (getgid() != getegid()) return 1; 
return 0; 

在Solaris上,它看起来如下:

return ((curproc->p_flag & SUGID) != 0);

我有点怀疑,但这部分是因为它难以理解像geteuidgetegid这样的函数在所有平台上都会返回 - 例如,BSD,Linux,Unix和Solaris。

第二个问题:Linux代码在语义上是否等同于Solaris代码?

第三个问题:geteuidgetegid跨平台的实施方式是否相同?对于我有三个身份证系统的系统怎么样 - 真实,有效和保存?

第四个问题:有效身份是唯一重要的身份吗?

如果进程以UID = 0开始并暂时删除权限,则saved ID将起作用。暂时删除root的进程不需要exec,也不应该被污染。

第五个问题:这是一个暂时摒弃根源的过程吗?

第六个问题:如果一个进程的有效ID是保存的ID会被认为是污点吗?

2 个答案:

答案 0 :(得分:4)

在为一个问题设计的系统中,有六个问题需要回答,特别是如果没有人知道所有六个问题的答案,但我会尝试......

1)issetugid()的目的是让库知道它们是否被用于以提升权限运行的程序中,以便它们可以避免风险行为,例如信任LD_LIBRARY_PATH,NLSPATH等环境变量这会让调用者加载可能滥用提升权限的模块。你可以看到一些关于它的历史讨论,如ncurses 4.1 security bug thread

2)该代码似乎不如BSD& Solaris版本,因为它没有考虑保存的setid位。

3)他们可能在不同的内核上有不同的实现 - 查看平台源代码以查找。

4,5& 6)不,是的,是的 - 一个可以将其euid或egid更改回更高级别的进程仍然不应该信任导致它加载用户提供的代码来利用它们的环境变量。

答案 1 :(得分:2)

我不知道issetugid(),但我可以通过阅读BSD或Solaris手册页来学习。该功能来自OpenBSD。

1)OpenBSD的issetugid(2)手册说,"如果进程是setuid或setgid,那么issetugid()函数返回1作为上一个或其他前一个execve()的结果系统调用。否则返回0。"然后建议使用issetugid()来检查环境变量中命名的文件是否可以安全打开。

2)不,您的Linux和Solaris代码不相同。运行setuid的进程可能会将其真实uid设置为其有效uid而不清除其环境变量。例如,uid_t uid = geteuid(); setresuid(uid, uid, uid);会将真实的uid和已保存的uid设置为有效的uid。然后您的Linux issetugid()将返回0,但Solaris issetugid()将返回1.

Solaris在exec时检查SUGID进程标志。 Illumos是Solaris的免费分支,在执行文件时在src/uts/common/os/exec.c中设置SUGID。 OpenBSD有类似的逻辑。 OpenBSD的手册说,

  

如果子进程执行新的可执行文件,则将确定新的issetugid状态。此状态基于现有进程的uid,euid,gid和egid权限以及可执行文件的模式。如果新的可执行文件模式是setuid或setgid,或者现有进程正在使用uid!= euid或gid!= egid执行新映像,则新进程将被视为issetugid。

Solaris和OpenBSD在执行时比较ID。你的Linux代码会延迟比较,直到调用issetugid(),因此它不等同。

3)geteuid()getegid()函数似乎在任何地方做同样的事情;他们只返回有效的用户ID和有效的组ID。

4)保存的ID并不重要。该过程可能在不清除其环境变量的情况下更改了这些ID。真实的,有效的或保存的ids都没有告诉我们为当前流程设置环境变量的人。

5)至少在OpenBSD和Solaris上,暂时删除root的进程不会受到污染。 OpenBSD的手册页说,

  

issetugid()系统调用的结果不受对setuid(),setgid()或其他此类调用的调用的影响。在fork()的情况下,子进程继承相同的状态。

     

issetugid()的状态仅受execve()的影响。

当进程使用setuid()或seteuid()临时删除root时,它不会执行文件,因此其issetugid()值不会更改。

但是FreeBSD,DragonFly BSD和NetBSD更严格地定义了issetugid()。 FreeBSD的issetugid(2)手册说,

  

如果一个进程因为execve(2)系统调用而创建,该系统调用设置了setuid或setgid位(并且结果给出了额外的特权),或者它已经改变了它的任何一个自开始执行以来真实,有效或已保存的用户或组ID。

使用这些系统,删除root的进程会强制其issetugid()值为1。

6)不,等于已保存ID的有效ID不会污染进程。如果确实如此,那么每个进程都会被污染,因为每个进程都将其保存的id设置为exec时的有效id。