关于保存用户ID的问题

Chr*_*ris 5 linux users setuid uid

据我了解,不同的用户ID如下(从进程的角度):

  • 真实用户 ID:拥有进程的用户 ID
  • 有效用户 ID:确定当前允许做什么和不允许做什么的用户 ID
  • 保存用户ID:基本是原来的有效用户ID,必要时可以恢复到原来的有效用户ID

现在我有两个问题:

  1. 在程序开始时将有效的用户 ID 保存在一个变量中会不会使保存的用户 ID 变得不必要?

  2. 如何在 C 程序中检索保存的用户 ID?我找不到任何这样做的功能。

ilk*_*chu 7

在程序开始时将有效的用户 ID 保存在一个变量中会不会使保存的用户 ID 变得不必要?

这不是用户空间程序记住什么的问题,而是内核允许它使用什么权限的问题。为了使用户之间的分离起作用,它必须是控制进程可以使用哪些用户 ID 的系统。否则任何进程都可能要求成为 root。

如何在 C 程序中检索保存的用户 ID?我找不到任何这样做的功能。

使用标准功能,您不能(只有getuid()geteuid())。不过,至少Linuxgetresuid()可以返回所有三个用户 ID。

无论如何,通常你不需要阅读它。在 setuid 程序的情况下,它允许在真实用户 ID 和有效用户 ID 之间切换,因此它作为有效用户 ID 的副本开始。

在 setuid 程序中,真正的用户 ID 是运行它的用户的 ID,有效和保存的用户 ID 是拥有该程序的用户的 ID。有效用户 ID 对权限检查很重要,因此如果进程想要暂时删除权限,它会在实际用户 ID 和保存的用户 ID 之间更改有效用户 ID。

内核以什么方式使用保存的用户 ID 来检查进程是否可以更改其用户 ID?这是否意味着当一个进程试图更改其有效用户 ID 时,内核会检查保存的用户 ID 以确保允许该进程这样做?

是的。Linux 手册页setuid()提到了这一点,但它有点隐藏:

ERRORS     
EPERM  The user is not privileged and uid does not match the real
       UID or saved set-user-ID of the calling process.
Run Code Online (Sandbox Code Playgroud)

换句话说,您只能将(有效)用户 ID 设置为真实 ID 或已保存 ID 之一。

手册页setreuid()更清楚地说明了这一点:

Unprivileged processes may only set the effective user ID to the real
user ID, the effective user ID, or the saved set-user-ID.
Run Code Online (Sandbox Code Playgroud)