【问题标题】:Use of setreuid() where _POSIX_SAVED_IDS is not set在未设置 _POSIX_SAVED_IDS 的情况下使用 setreuid()
【发布时间】:2012-10-05 20:35:15
【问题描述】:

我正在探索 suid 区域,发现自己无法回答这个问题。为了这个问题,我们假设程序二进制文件是 suid,由用户 1001 拥有并由用户 1000 运行(非 root) - 因此 RUID=1000,EUID=1001。

当设置了_POSIX_SAVED_IDS 时,我可以使用setuid()seteuid() 分别在1000 和1001 之间更改RUID 和EUID。

但是,当_POSIX_SAVED_IDS 未设置时,seteuid(1000) 将在以后使seteuid(1001) 变得不可能,setuid(1001) 稍后将对setuid(1000) 执行相同的操作。

为了将 EUID 更改为 RUID 并保留稍后返回的可能性,我在GNU Setuid Program Example 找到的解决方案是使用setreuid(1001,1000)(交换它们)。这对程序有什么影响,因为它改变了 RUID?据我了解,它改变了进程的所有者,因此对杀死进程或与进程交互的权限有影响。
哪些系统不使用_POSIX_SAVED_IDS?

【问题讨论】:

    标签: c linux permissions suid


    【解决方案1】:

    由于 POSIX 要求 _POSIX_SAVED_IDS 定义为正值,因此任何系统都不应缺少 _POSIX_SAVED_IDS

    来源:http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html

    【讨论】:

    • 当然,除了那些没有声称符合 POSIX 合规性的人,这是 OP 的最后一个问题......
    • 我认为保存的 id 过去是可选的,但后来变成了强制性的。我怀疑仍然存在没有保存 id 的系统,除非您可以使用非常过时的版本,在这种情况下,它们可能充满漏洞并且使用起来不太实用......
    • 这可能是历史,但如果一个系统不声称是 POSIX 兼容的,那么它没有义务实现 _POSIX_ANYTHING...当然现在大多数 *nix-en 都是 POSIX 兼容的.不确定 Windows 变体,它们绝对不是过去的,我知道...
    • Here 在底部显示“与 _POSIX_SAVED_IDS 关联的功能现在是强制性的。这是 FIPS 要求。”我发现的唯一没有它的操作系统是大约 2001 年之前的 FreeBSD。谢谢
    【解决方案2】:

    我只是不得不处理这个问题,到目前为止,下面的部分还没有得到正确的回答。

    为了将 EUID 更改为 RUID 并保留稍后返回的可能性,我在 GNU Setuid 程序示例中找到的解决方案是使用 setreuid(1001,1000) (交换它们)。这对程序有什么影响,因为它改变了 RUID?据我了解,它改变了进程的所有者,因此对杀死进程或与进程交互的权限有影响。

    无处不在的情况是,EUID 是唯一用于访问文件或能够终止进程等权限的东西(可能会出现一些罕见的例外情况)。 这个想法是您可以在 EUID 和 RUID 之间来回切换,但只能在它们之间切换。内核需要跟踪这两个 id。

    seteuid 对于非 root 用户只允许切换到 EUID、RUID 和 - 如果内核支持它 - SUID 之一。

    对于符合 POSIX 的系统,SUID 是可用的,所以会发生这种情况:

    // uids are: EUID=1001, RUID=1000, SUID=1001
    seteuid(1000) ; // works because RUID=1000
    // uids are: EUID=1000, RUID=1000, SUID=1001
    seteuid(1001); // works because SUID=1001
    

    在没有 SUID 的系统上:

    // uids are: EUID=1001, RUID=1000
    seteuid(1000); // works because RUID=1000
    // uids are: EUID=1000, RUID=1000
    seteuid(1001); // fails, neither EUID, nor RUID is 1001
    

    相反

    // uids are: EUID=1001, RUID=1000
    setreuid(1001, 1000) ; // works because EUID=1001 and RUID=1000
    // uids are: EUID=1000, RUID=1001
    setreuid(1000, 1001); // works because EUID=1000 and RUID=1001
    

    我还没有找到在符合 POSIX 的系统上永久删除权限的标准方法,因为这需要修改 SUID。只有 gnu 扩展可用:

    // uids are: EUID=1001, RUID=1000, SUID=1001
    setresuid(1000, 1000, 1000);
    // uids are: EUID=1000, RUID=1000, SUID=1000
    

    见:https://people.eecs.berkeley.edu/~daw/papers/setuid-usenix02.pdf

    【讨论】:

      猜你喜欢
      • 2020-01-04
      • 2013-05-04
      • 2014-02-22
      • 2023-02-06
      • 2015-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多