超级用户进程是否可以更改进程的真实用户 ID 和组 ID,而不与密码文件中的内容匹配?

超级用户进程是否可以更改进程的真实用户 ID 和组 ID,而不与密码文件中的内容匹配?

来自APUE

进程的真实用户 ID 和真实组 ID 标识了我们的真实身份。这两个字段取自我们登录时在密码文件中的输入。通常,这些值在登录会话期间不会更改,尽管有多种方法可以更改 一个超级用户进程来改变它们

超级用户进程是否可以更改进程的真实用户 ID 和真实组 ID,从而使真实用户 ID 和真实组 ID 之间的关系与密码文件中的关系不匹配?例如,如果用户Tim不是ocean密码文件中的组成员,超级用户进程是否可以将进程的真实用户 ID 和真实组 ID 分别更改为Timocean

答案1

是的,超级用户进程可以将其真实用户 ID 和真实组 ID 更改为它想要的任何值。/etc/passwd和中的值/etc/shadow是应设置哪些值的配置,但不是对可能值的限制。

编辑#1

这意味着像这样的程序login将从文件中读取值,因此这些文件是配置文件或输入文件。它们并不限制程序可以做什么。超级用户进程可以将任何值传递给内核,而内核不会检查任何文件。

一个程序可以调用

setgid (54321);
setuid (12345);

即使任何文件中都没有提到这两个 id,这也是可行的。

答案2

密码文件和组文件不被读取,它们仅由登录进程读取,以设置真实用户ID和真实组ID。

内核中没有任何内容提及这些文件。登录必须打开文件、处理它们并设置两个 ID。可以采用不同的编写方式从其他地方获取这些 ID。例如,来自网络数据库。

任何具有 CAP_SETUID 能力的进程都可以设置这些 ID,root 具有此能力。

Unix 中的安全模型部分在内核中实现,部分在以增强功能运行的进程中(例如作为 root)实现。


请注意,/etc/passwd/etc/group也可以由和 以及任何其他需要将用户/组名称转换为用户/组 ID 或从用户/组 ID 转换的程序读取。 (他们可以通过图书馆来做到这一点,而不是知道存储这些详细信息的替代方法。)lsps

答案3

除其他外,其目的/etc/passwd是翻译用户的姓名到用户的用户识别码。如果您不关心 bob 的 UID 是什么,则不需要该文件。如果您只想更改为任意 UID/GID,请使用相关的系统调用:

int setuid(uid_t uid);
int setgid(gid_t gid);

CAP_SETUID请注意,带有和 的特权进程CAP_SETGID 能力(根进程通常具有)只能更改自己的 UID 和 GID,而不能更改其他正在运行的进程的 UID 和 GID。

答案4

我最近创建了一个 Linux 内核模块来做到这一点(https://github.com/xuancong84/chown-pid)。到目前为止,还没有用户级程序可以做到这一点。

您需要构建内核模块,cd将其放入项目文件夹中并运行make。如果成功,将会产生chown-pid.ko.

然后,

insmod chown-pid.ko arg_pid=<PID> arg_gid=<UID> arg_act='set_uid' && rmmod chown-pid
insmod chown-pid.ko arg_pid=<PID> arg_gid=<GID> arg_act='set_gid' && rmmod chown-pid

相关内容