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

Tim*_*Tim 1 process files uid

来自 APUE

保存的 set-user-ID 是通过exec函数从有效用户 ID 复制而来的。如果设置了文件的设置用户 ID 位,则 exec存储来自文件用户 ID 的有效用户 ID保存该副本。

是不是意味着

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

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

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

Eri*_*ikF 5

中的文档credentials(7)对 Linux 系统进行了一些澄清:

用户和组标识符

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

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

  • 真实用户 ID 和真实组 ID。这些 ID 决定谁拥有进程。进程可以使用 getuid(2).

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

  • 保存的 set-user-ID 和保存的 set-group-ID。这些 ID 在 set-user-ID 和 set-group-ID 程序中使用,以保存执行程序时设置的相应有效 ID 的副本(请参阅 参考资料execve(2))。set-user-ID 程序可以通过在其真实用户 ID 和保存的 set-user-ID 中的值之间来回切换其有效用户 ID 来承担和放弃特权。这种切换是通过调用完成seteuid(2)setreuid(2)setresuid(2)。一组基团的ID使用程序执行类似的任务setegid(2)setregid(2)setresgid(2)。进程可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

这是文件:

server /home/erik # ls -l perms
-r-sr-sr-x 1 nobody nobody 8280 Apr 26 00:36 perms
Run Code Online (Sandbox Code Playgroud)

运行为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
Run Code Online (Sandbox Code Playgroud)

运行为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
Run Code Online (Sandbox Code Playgroud)

正如我的测试程序所示,如果文件是 set-ID,则 EUID/EGID 以文件上的所有者/组开始(只有 set-UID 和 set-UID+GID 权限有效!),但可以更改如果程序需要,在它和调用者的真实 ID 之间。