Archive:

Linux 中各种各样的 uid


Linux 用户 ID

Linux 进程会记录三种用户 ID,分别为 ruid, euidsuid

真实用户 ID,ruid (或者简称为 uid) 是启动该进程的用户的 ID,每个用户都拥有唯一的 ID。

有效用户 ID(euid/effective user ID)是系统判断当前进程权限所使用的 ID,在大多数情况下,euid=ruid。但 SetUID 可执行文件就是一个例外,当一个 SetUID 可执行文件执行时,euid 会被设置为该文件的拥有者。

passwd 就是一个 SetUID 程序,任何用户都可以执行它来修改自己的密码。但修改密码这个操作是一个特权行为。

$ ll /usr/bin/passwd
-r-s–x–x 1 root root 21944 Feb 12  2006 /usr/bin/passwd;

保存用户 ID(suid,不要与 SetUID 程序弄混),则是用于让一个特权程序放弃自己的权限来进行一些操作,并且在操作完毕后恢复特权状态。

当一个非特权进程修改自身的 euid 时,它只能将 euid 设为 ruid, euid 或者 suid 当中的值。suid 允许一个普通用户启动一个 SetUID 进程,并且让它降低权限为普通用户,最后仍能返回特权状态。

set*uid 系统调用

int setuid(uid_t uid);

setuid() sets the effective user ID of the calling process. If the calling process is privileged (more precisely: if the process has the CAP_SETUID capability in its user namespace), the real UID and saved set-user-ID are also set.

setuid 通常只修改 euid,但当调用进程为特权进程时,setuid 会同时设置 suidruid

int setreuid(uid_t ruid, uid_t euid); int setresuid(uid_t ruid, uid_t euid, uid_t suid);

An unprivileged process may change its real UID, effective UID, and saved set-user-ID, each to one of: the current real UID, the current effective UID, or the current saved set-user-ID. A privileged process (on Linux, one having the CAP_SETUID capability) may set its real UID, effective UID, and saved set- user-ID to arbitrary values.

非特权进程只能将自己的 ruideuidsuid 设置为三者中的其中之一,但特权进程(拥有 CAP_SETUID 特权)可以随意设置自己的 *uid

执行程序: execvesystem

tl;dr

  • 如果被执行的程序是 SetUID 程序,则 euid 会被变更为该文件的拥有者,如果不是,则 euid 保持不变。
  • suid 会被设为之前euid
  • ruid 保持不变。

bash

bash 具有安全限制,在正常情况下由 SetUID 程序启动 bash (例如,system("/bin/bash")),bash 会将自己的 euid 设为 ruid。可以通过 -p 参数让 bash 保留之前的权限。