文件的基本权限(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、seccomp、Landlock、LSM 等软件边界机制,汇成一张内核对用户态信任的全景图。
【操作系统百科】内存回收
Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。
【操作系统百科】交换
swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。
【操作系统百科】Slab/SLUB 分配器
buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。