xattr
extended attributes扩展属性
文件常规属性之外另行定义的可以关联到文件的(或多或少)任意属性
linux上所有主要的硬盘文件系统(Ext3/4 xfs btrfs)都支持扩展属性
概述
- 一个扩展属性就是与文件系统对象关联的一个”名称/值”对 名称就是普通字符串;值可以是文本,也可以是二进制数据,内核对值的内容没有限制
- 属性可以定义,也可以不定义;如果定义了属性,可以有值,也可以没有
- 属性名称按命名空间划分访问属性也需要指定命名空间(如 security.ima)
- 每个文件通常都只关联了所有可能扩展属性的一个子集,扩展属性存储在常规的inode数据结构之外,以免增加该结构在内存中的长度和浪费磁盘空间。
- 如果两个文件的扩展属性集合是相同的,则二者可共享同一磁盘表示,有助于节省磁盘空间
存储
存储位置
- inode尾部未使用空间 (允许动态inode长度的文件系统才支持)
- 磁盘上一个独立的数据块
存储空间上限
如果使用inode末尾空间的话,ext3_xattr_header 和 value 的总长度不超过一个数据块加上inode中空闲空间的长度
否则最多占用一个数据块,因此 struct ext3_xattr_header->h_blocks的值总是为1
磁盘布局
ext3处理
每个定义的扩展属性都有对应的handler,包含get set list三个常规操作,会注册到文件系统的super_block中
对应系统调用 getxattr setxattr listxattr
struct xattr_handler { const char *name; const char *prefix; int flags; /* fs private flags */ bool (*list)(struct dentry *dentry); int (*get)(const struct xattr_handler *, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size); int (*set)(const struct xattr_handler *, struct dentry *dentry, struct inode *inode, const char *name, const void *buffer, size_t size, int flags); };
SYSCALL VFS Layer Special FileSystem
setxattr --> vfs_setxattr --> inode->i_sb->s_xattr[i]->set
getxattr --> vfs_getxattr --> inode->i_sb->s_xattr[i]->get
listxattr --> vfs_listxattr --> inode->i_op->listxattr
ext3_xattr_user_get -> ext3_xattr_get
ext3_xattr_ibody_get // 尝试在inode空闲空间中查找指定的属性
ext3_xattr_block_get // ibody失败再从外部属性数据块去读
ext3_xattr_set -> ext3_xattr_set_handle
ext3_xattr_ibody_find // 先尝试在inode的空闲空间中查找指定属性
ext3_xattr_block_find // ibody失败 再在inode外部的数据块中查找
ext3_xattr_ibody/block_set // 属性值value入参为空则删除该属性
// 入参携带值,则替换已有的;或者新创建一个属性
ext3_xattr_list
ext3_xattr_ibody_list
ext3_xattr_block_list
应用
扩展属性的两个应用场合
- ACL 访问控制表 用于linux的自主访问控制 明确各个用户及其允许的操作 并关联到文件
- IMA 完整性度量架构
隶属于安全模块 用于系统实时监测可执行文件的内容完整性,检测文件是否被篡改
a. 针对文件数据内容计算hash值 存储至文件扩展属性security.ima
b. 针对文件扩展属性计算hash值 存储至文件扩展属性security.evm
包含 security.ima security.selinux security.capability security.SMACK64扩展属性项
和安全模块的关联
vfs_setxattr security_inode_setxattr ima_inode_setxattr // 设置当前文件iint 缓存信息 IMA_CHANGE_XATTR标志位 // IMA process_measurement函数度量时会检查标识位, // 有设置则iint->measured_pcrs 清零操作,后续可能需要重新扩展PCR evm_inode_setxattr // 保护evm xattr不被修改,除非持有CAP_MAC_ADMIN权限
参考索引
《深入linux内核架构》