当 set-user-ID 位打开时,进程的 EUID 和保存的 set-user-ID 是否都更改为文件的用户 ID?

当 set-user-ID 位打开时,进程的 EUID 和保存的 set-user-ID 是否都更改为文件的用户 ID?

来自APUE

保存的设置用户ID是通过exec函数从有效用户ID复制而来的。如果文件的设置用户 ID 位已设置,则保存此副本 exec存储文件用户 ID 中的有效用户 ID。

是不是意味着

  • 首先进程的 EUID 更改为文件的用户 ID,

  • 那么进程保存的set-user-ID是否会更改为进程的EUID?

那么进程的 EUID 和保存的 set-user-ID 都更改为文件的用户 ID 吗?

答案1

文档在credentials(7)针对 Linux 系统澄清了这一点:

用户和组标识符

每个进程都有各种关联的用户和组 ID。这些 ID 是整数,分别使用类型uid_tgid_t表示(在 中定义<sys/types.h>)。

在 Linux 上,每个进程都有以下用户和组标识符:

  • 真实用户ID和真实组ID。这些 ID 确定谁拥有该进程。进程可以使用 获取其真实用户(组)ID getuid(2)

  • 有效用户ID和有效组ID。内核使用这些 ID 来确定进程在访问消息队列、共享内存和信号量等共享资源时所拥有的权限。在大多数 UNIX 系统上,这些 ID 还确定访问文件时的权限。但是,Linux 使用下面描述的文件系统 ID 来执行此任务。进程可以使用 获取其有效用户(组)ID geteuid(2)

  • 已保存的设置用户 ID 和已保存的设置组 ID。这些 ID 在 set-user-ID 和 set-group-ID 程序中用于保存程序执行时设置的相应有效 ID 的副本(请参阅 参考资料execve(2))。设置用户 ID 程序可以通过在其真实用户 ID 和保存的设置用户 ID 中的值之间来回切换其有效用户 ID 来获取和放弃特权。这种切换是通过调用seteuid(2)setreuid(2)、 或 来完成的setresuid(2)。 set-group-ID 程序使用setegid(2)setregid(2)或执行类似的任务setresgid(2)。进程可以使用 获取其保存的 set-user-ID (set-group-ID) getresuid(2)

[...]

我编写了一个测试程序来看看会发生什么:

#define _GNU_SOURCE

#include <stdio.h>
#include <unistd.h>

int getuids(uid_t *uids) {
  if(getresuid(&uids[0], &uids[1], &uids[2]) == -1) {
    perror("Unable to get UIDs\n");
    return 0;
  }
  return 1;
}

int getgids(gid_t *gids) {
  if(getresgid(&gids[0], &gids[1], &gids[2]) == -1) {
    perror("Unable to get GIDs\n");
    return 0;
  }
  return 1;
}

int main(void) {
  uid_t uids[3];
  gid_t gids[3];

  if(getuids(uids) && getgids(gids)) {
    printf("Real ID: user %d, group %d\n", (int)uids[0], (int)gids[0]);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
    printf("Set-ID: user %d, group %d\n", (int)uids[2], (int)gids[2]);

    seteuid(uids[0]);
    getuids(uids);
    getgids(gids);
    printf("Effective ID: user %d, group %d\n", (int)uids[1], (int)gids[1]);
  }

  return 0;
}

这是文件:

server /home/erik # ls -l perms
-r-sr-sr-x 1 nobody nobody 8280 Apr 26 00:36 perms

运行为root

server-calgary /home/erik # ./perms
Real ID: user 0, group 0
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 0, group 65534

运行为erik

erik@server ~ $ ./perms
Real ID: user 1000, group 1000
Effective ID: user 65534, group 65534
Set-ID: user 65534, group 65534
Effective ID: user 1000, group 65534

正如我的测试程序所示,如果文件是 set-ID,则 EUID/EGID 以文件上的所有者/组的任何内容开头(只有 set-UID 和 set-UID+GID 权限有效!),但它可以更改如果程序需要的话,可以在该 ID 和呼叫者的真实 ID 之间进行。

相关内容