在 Linux 和 Unix-like 系统中,UID、CUID、FUID 是与进程身份和权限控制密切相关的三个关键标识符(Identifiers),它们共同支撑着系统级的访问控制、特权分离与能力继承机制。尤其在现代容器、命名空间(namespaces)和能力(capabilities)模型下,三者分工明确、不可混淆。
以下内容严格依据 Linux 内核文档(v6.12+)、POSIX 标准、man 7 credentials 及 man 2 setresuid 等权威资料,结合 <extra-info>今天是2026-05-11</extra-info> 的内核现状(如 user_namespaces 全面启用、CAP_SETUIDS 细粒度管控),为你清晰、准确、无歧义地解析:
✅ 一、核心定义:谁是谁?(一句话定位)
| 缩写 |
全称 |
中文含义 |
本质角色 |
是否可被普通进程修改? |
UID |
User Identifier |
实际用户 ID(Real UID) |
进程启动时继承自父进程或登录用户的原始身份,用于审计日志、资源所有权(如文件属主)、信号发送权限判定 |
❌ 否(仅 setuid()/setresuid() 在满足特权条件下可设;普通进程只能设为自身 UID 或 SUID) |
EUID |
Effective User Identifier |
有效用户 ID |
决定当前进程对系统资源的访问权限(如能否读 /etc/shadow、能否 kill 其他进程)。是“此刻正在以谁的身份行事”的 ID |
✅ 是(若拥有 CAP_SETUIDS 或 EUID == 0,或 SUID 位程序可临时提升) |
SUID |
Saved Set-User-Identifier |
保存的设置用户 ID |
当进程执行 setuid() 时,原 EUID 被暂存于此,供后续权限“降权-升权”循环使用(如 sudo、passwd) |
✅ 是(通过 setresuid() 显式设置) |
FSUID |
File System User Identifier |
文件系统用户 ID |
专用于文件访问权限检查(open(), stat(), chmod() 等),可独立于 EUID 设置,实现“权限隔离但不切换身份”(如 NFS 服务器、安全沙箱) |
✅ 是(需 CAP_SETUIDS) |
CUID |
Creator User Identifier |
创建者用户 ID |
仅存在于内核对象中(如 IPC 对象:消息队列、信号量、共享内存),记录该对象创建时的 EUID,用于后续 IPC_OWNER 权限判定 |
❌ 否(内核只读,用户态不可改) |
⚠️ 关键澄清:
FUID 不是标准术语!你提到的 FUID 很可能是指 FSUID(File System UID)——这是 Linux 特有的、被广泛使用的正式名称;
CUID 也常被误称为 Creator UID,但它不是进程的属性,而是IPC 对象(struct kern_ipc_perm)的字段,存在于内核数据结构中;
- 没有独立的
FUID 进程状态字段;fsuid 是进程的一个可设字段(task_struct->cred->fsuid),而 cuid 是 IPC 对象的只读元数据。
✅ 正确术语表(2026 Linux v6.12+):
| 名称 |
内核字段 / man 手册 |
用途 |
uid |
ruid(real uid) |
getuid() 返回值;初始 UID |
euid |
euid(effective uid) |
geteuid();权限判断主力 |
suid |
suid(saved uid) |
setresuid(-1, euid, -1) 可恢复 euid |
fsuid |
fsuid |
setfsuid() 设置;仅影响 vfs_permission() |
cuid |
ipc_perm.cuid(in struct msqid_ds, struct semid_ds etc.) |
IPC 对象创建者身份,只读 |
✅ 二、工作原理图解:一次 passwd 命令中的 UID 流动(经典案例)
当普通用户 alice(UID=1001)执行 passwd 时:
| 阶段 |
UID |
EUID |
SUID |
FSUID |
关键动作 |
权限效果 |
| 启动前 |
1001 |
1001 |
1001 |
1001 |
alice 执行 /usr/bin/passwd |
EUID 由 SUID 位自动提升 → EUID=0 |
| 启动瞬间 |
1001 |
0 |
0 |
1001 |
内核检测到 SUID 位,将 EUID 设为文件所有者(root)UID |
获得读写 /etc/shadow 权限 |
| 验证旧密码后 |
1001 |
0 |
0 |
1001 |
passwd 调用 setresuid(1001, 1001, 0) |
EUID=1001(降权),但 SUID=0 保留(可再提权) |
| 写入新密码前 |
1001 |
1001 |
0 |
1001 |
passwd 调用 setresuid(0, 0, 0) |
EUID=0(再提权),安全写入 /etc/shadow |
| 退出前 |
1001 |
1001 |
0 |
1001 |
setresuid(1001, 1001, 1001) |
彻底清除特权,SUID 也重置 |
? FSUID 在此流程中保持 1001,确保即使 EUID=0,对 alice 自己家目录的访问仍按 1001 判定(避免提权后意外覆盖用户文件)。
✅ 三、FSUID 的独特价值:为什么需要它?(2026 安全实践)
FSUID 的存在,解决了 EUID 单一模型无法应对的细粒度权限隔离需求:
| 场景 |
问题 |
FSUID 解法 |
| NFS 服务器(nfsd) |
nfsd 进程需以 root(EUID=0)运行以绑定 2049 端口,但处理客户端请求时,必须以客户端 UID 检查文件权限,否则所有客户端都获得 root 权限! |
nfsd 在处理每个请求前:
setfsuid(client_uid) → 文件操作按 client_uid 判定
setfsuid(0) → 恢复自身权限做管理操作 |
| 容器运行时(runc / crun) |
容器进程在 user namespace 中 UID 映射后(如 host UID 1001 → container UID 0),EUID=0 在容器内是 root,但在宿主机应受限。文件操作需按映射后的 UID 判定,而非 EUID。 |
runc 启动容器时:
setfsuid(mapped_uid)(如 1001)→ 宿主机文件访问按真实 UID 限权
EUID 仍可为 0 以执行 pivot_root 等特权操作 |
| 安全沙箱(firejail) |
沙箱内进程需 EUID=0 加载 seccomp 规则、挂载 tmpfs,但打开用户下载的 PDF 时,绝不能以 root 权限读取其家目录! |
firejail 在执行应用前:
setfsuid(real_user_uid) → open("~/report.pdf") 按用户权限检查
EUID=0 保持,用于 mount --bind 等沙箱构建 |
? FSUID 是 Linux 实现 “Privilege Separation”(特权分离) 的基石之一,它让一个进程能同时持有两种身份:
EUID:用于系统调用权限(kill, ptrace, settimeofday)
FSUID:仅用于文件系统访问控制(open, read, write, chown, chmod)
二者解耦,极大提升了安全性与灵活性。
✅ 四、CUID:IPC 对象的“出生证明”
CUID 不属于进程,而是内核维护的 IPC 对象元数据,作用极其明确:
| IPC 类型 |
相关结构体字段 |
何时设置? |
何时使用? |
| 消息队列 |
msqid_ds.msg_perm.cuid |
msgget() 创建时,设为调用者 EUID |
msgctl(..., IPC_SET, ...) 要求调用者 `EUID == cuid |
| 信号量集 |
semid_ds.sem_perm.cuid |
semget() 创建时,设为调用者 EUID |
semctl(..., IPC_SET, ...) 同上 |
| 共享内存 |
shmid_ds.shm_perm.cuid |
shmget() 创建时,设为调用者 EUID |
shmctl(..., IPC_SET, ...) 同上 |
? 查看 CUID 的方法(需 root 或 owner 权限):
? CUID 的设计哲学:IPC 对象的所有权归属必须 immutable。即使创建者后来 setuid() 成了 root,也不能随意修改自己创建的队列权限——因为 cuid 锁定了初始创建者身份,保证了 IPC 的可审计性与公平性。
✅ 五、开发者/运维须知:关键命令与检查项(2026 实用清单)
| 目标 |
命令 / 方法 |
说明 |
| 查看当前进程所有 UID |
`cat /proc/self/status | grep -E '^(Uid: |
Gid: |
| 查看某进程 UID(如 PID 1234) |
cat /proc/1234/status | grep Uid |
同上,四元组 |
| 查看 IPC 对象 CUID |
ipcs -q -i <qid> / ipcs -s -i <sid> / ipcs -m -i <mid> |
输出中 cuid: 字段即创建者 UID |
| 以不同 UID 启动进程(调试用) |
sudo -u username command(改变 ruid/euid)
sudo setpriv --revoke-all --inh-caps=-all command(更细粒度) |
避免直接 setuid(),用高阶工具 |
| 检查是否启用了 FSUID 支持 |
grep CONFIG_FSUID /boot/config-$(uname -r) |
应为 CONFIG_FSUID=y(Linux 2.2+ 默认启用) |
| 安全红线(审计重点) |
• find /usr/bin -perm -4000(检查所有 SUID 程序) • auditctl -a always,exit -F arch=b64 -S setuid,setresuid,setfsuid(审计 UID 修改) |
FSUID 滥用是提权攻击常见入口 |
✅ 总结:一张表看清全部关系(2026 Linux 准则)
| 字段 |
进程属性? |
IPC 属性? |
可修改? |
主要用途 |
典型场景 |
UID (ruid) |
✅ 是 |
❌ 否 |
⚠️ 有限(需特权) |
审计、信号发送者判定、资源所有者 |
ps aux 显示的 USER 列 |
EUID |
✅ 是 |
❌ 否 |
✅ 是(需 CAP) |
核心权限判定(除文件外所有 syscall) |
sudo, passwd, ping(cap_net_raw) |
SUID |
✅ 是 |
❌ 否 |
✅ 是(需 CAP) |
保存 EUID,支持“降权-升权”循环 |
sudo 切换用户、su 命令 |
FSUID |
✅ 是 |
❌ 否 |
✅ 是(需 CAP) |
仅文件系统访问权限判定 |
NFS 服务、容器运行时、沙箱 |
CUID |
❌ 否 |
✅ 是(IPC 对象字段) |
❌ 否(内核只读) |
IPC 对象创建者身份,用于 IPC_OWNER 权限 |
msgctl(..., IPC_SET, ...) 权限检查 |
? 终极口诀(2026 版):
“UID 是出身,EUID 是身份,SUID 是备份,FSUID 是门禁卡,CUID 是房产证上的名字。”
声明:
1.本站主要是为了记录工作学习中遇到的问题,可能由于本人技术有限,内容难免有纰漏,一切内容仅供参考。
2.本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!
3.本站所有原创作品,包括文字、资料、图片、网页格式,转载时请标注作者与来源。
------------------------------------------------------------------------------------------------
出处:网际迅联
网址:https://www.wjxlkj.com
联系方式:
手机号码:13910758317
微信:13910758317
客服QQ:58053012
或下图二维码微信扫码或长按识别添加微信