文件的基本权限(rwx + uid/gid)不够灵活——POSIX ACL 做细粒度访问控制、capability 做特权分解、SELinux label 做强制访问控制。这些都存在 xattr(扩展属性)里。
一、先看图
flowchart TD
INODE[inode] --> XATTR[xattr 存储<br/>inline / block]
XATTR --> USER["user.*<br/>用户自定义"]
XATTR --> SECURITY["security.*<br/>SELinux label<br/>AppArmor<br/>capabilities"]
XATTR --> SYSTEM["system.*<br/>POSIX ACL"]
XATTR --> TRUSTED["trusted.*<br/>需 CAP_SYS_ADMIN"]
classDef ns fill:#388bfd22,stroke:#388bfd,color:#adbac7;
classDef store fill:#a371f722,stroke:#a371f7,color:#adbac7;
class INODE,XATTR store
class USER,SECURITY,SYSTEM,TRUSTED ns
二、xattr 基础
2.1 API
setxattr("/path", "user.mykey", "value", 5, 0);
getxattr("/path", "user.mykey", buf, sizeof(buf));
listxattr("/path", buf, sizeof(buf));
removexattr("/path", "user.mykey");Shell:
setfattr -n user.mykey -v "hello" /tmp/file
getfattr -d /tmp/file2.2 四命名空间
- user.:任意用户可设(对普通文件)
- security.:安全模块用(SELinux、AppArmor、capability)
- system.:POSIX
ACL(
system.posix_acl_access、system.posix_acl_default) - trusted.:只有 CAP_SYS_ADMIN 进程能读写
2.3 存储
ext4:小 xattr inline 在 inode 里(256 字节内);大的放额外 block。
btrfs / XFS:类似,各有自己的 xattr item。
三、POSIX ACL
3.1 为什么
传统 rwx 只有 owner/group/other 三类。要给特定用户 alice 读权限,其他人不行 → 需要 ACL。
3.2 设置
setfacl -m u:alice:r /tmp/data
setfacl -m g:devteam:rw /tmp/data
getfacl /tmp/data3.3 内核实现
ACL 存在 system.posix_acl_access(文件
ACL)和 system.posix_acl_default(目录默认
ACL,新建文件继承)。
内核在 permission() 里检查 ACL。
3.4 注意事项
ls -l权限位后面多一个+表示有 ACLchmod会覆盖 ACL 的 mask 条目- 备份工具需要
--xattrs --acls才能保留
四、文件 capabilities
传统特权模型:root 拥有一切。capabilities 把特权拆成 40+ 个独立 cap。
文件级 capability:
setcap cap_net_bind_service=+ep /usr/bin/myserver
getcap /usr/bin/myserver存在 security.capability xattr 里。exec
时内核合并到进程有效 capability set。
常用 cap:
CAP_NET_BIND_SERVICE:绑定 <1024 端口CAP_NET_RAW:raw socketCAP_SYS_PTRACE:ptrace 其他进程CAP_DAC_OVERRIDE:跳过文件权限检查
五、SELinux / AppArmor label
ls -Z /etc/passwd
# system_u:object_r:passwd_file_t:s0 /etc/passwdLabel 存在 security.selinux
xattr。内核在每次文件操作时用 LSM hook 检查。
容器场景:需要
--security-opt label=type:container_file_t 或
--privileged。
六、备份与 xattr
# tar 保留 xattr
tar --xattrs --xattrs-include='*' -cf backup.tar /data
# rsync 保留
rsync -avX /src/ /dst/
# cp 保留
cp --preserve=xattr file1 file2不保留 → ACL、capability、SELinux label 全丢。
七、容器镜像与 xattr
OCI 镜像层是 tar 包——需要保留 security.* 和
system.* xattr。
overlay2 存储驱动:
- whiteout 用
trusted.overlay.opaquexattr 标记 - metacopy 用 xattr 标记”只复制元数据”
构建镜像时工具(buildkit、podman)需要正确处理 xattr。
八、xattr 大小限制
- ext4:单个 xattr 值最大约 65536 字节(受 block size)
- btrfs:限制较宽
- XFS:名+值 ≤ 64KB
- 总 xattr 空间受 inode/block 限制
过多 xattr → inode 扩展开销增大、备份慢。
九、观察
getfattr -d -m - /tmp/file # 列出所有命名空间 xattr
getfacl /tmp/file # ACL
getcap /usr/bin/* # 扫描 capability
ls -Z /etc/ # SELinux label
# 统计 xattr 使用
debugfs -R "stat <inode_no>" /dev/sda1 | grep -i xattr十、小结
- xattr 是 inode 的元数据扩展点
- POSIX ACL、capability、SELinux label 都用 xattr 存储
- 备份/迁移/容器镜像必须保留 xattr
- 文件 capability 替代 setuid → 更细粒度的特权
参考文献
man 7 xattrDocumentation/filesystems/ext4/attributes.rstman 5 aclinclude/uapi/linux/capability.h- Tetsuo Handa, “Linux capabilities overview.” 2018
工具
setfattr/getfattrsetfacl/getfaclsetcap/getcapls -Z(SELinux)attr(1)
文章导航
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【操作系统百科】内核与用户态的边界:copy_from_user、pin、seccomp、capability
内核代码不能像用户代码那样自由访问任何指针。本文围绕 Linux 的 access_ok / copy_from_user / get_user_pages / pin_user_pages / __user 注解,说明用户页在内核视角的生命周期;再把视角扩展到 capability、namespace、seccom…
CPU 调度:CFS 的虚拟运行时间与 EEVDF 的虚拟截止期
从比例份额调度的论文谱系出发,对照 Linux v6.6 与 v6.12 fair.c 源码,解释 CFS 的 vruntime、EEVDF 的 lag/eligible/deadline,并用确定性模拟复现延迟与 lag 的差异。
I/O 调度:在寻道、队列深度与公平性之间取舍
从电梯算法到 blk-mq,解释 Linux I/O 调度器为何在 HDD 上排序、在共享设备上保公平、在 NVMe 上常选择 none,并用确定性模拟展示寻道距离与队列尾延迟的取舍。
用户态内存分配器:size class、线程缓存与碎片边界
从 Wilson 分配器综述到 jemalloc、gperftools tcmalloc 与 mimalloc 的源码路径,解释 size class、线程缓存、跨线程释放和 RSS 碎片;用可复现实验说明不能只凭 allocator 名字下结论。