linux模块后缀,Linux自主访问控制机制模块详细分析之文件系统的扩展属性

原标题:Linux自主访问控制机制模块详细分析之文件系统的扩展属性

2.3.1文件系统的扩展属性2.3.1.1扩展属性

扩展属性是指与文件相关联的“名称/值”对,名称是一个普通的字符串,而值则没有什么限制。为了对属性名进行管理,Linux采用命名空间进行,这些命名空间以宏的形式定义在include/linux/xattr.h中,具体定义如下所示:

/* Namespaces */

#define"os2."

#define(sizeof () - 1)

#define"security."

#define(sizeof () - 1)

#define"system."

#define(sizeof () - 1)

#define"trusted."

#define(sizeof () - 1)

#define"user."

#define(sizeof () - 1)

为了操作扩展属性,内核提供了以下四个系统调用:

(1) setxattr() 用于根据参数来设置或替换某个扩展属性的值,或者创建一个新的扩展属性

(2) getxattr() 用于获取指定扩展属性的值

(3) listxattr() 用于获取文件的扩展属性列表

(4) removexattr() 用于删除指定的扩展属性

对于上述函数,它们还有前缀为l和前缀为f的变体,前缀为l的变体用于对符号链接本身的扩展属性进行操作;前缀为f的变体用于对通过文件描述符指定的文件进行处理。对于这三种类型的系统调用,它们之间唯一的区别在于查找目标对象关联的dentry实例的方式,当找到目标对象对应的目录项之后,它们将会调用相同的函数来进行进一步的处理。下面主要针对setxattr()类系统调用进行分析,对于这些函数,在它们通过相应的方式获得目标对象对应的目录项之后,均会调用setxattr()函数进行进一步的处理。setxattr()函数真正用于根据参数来设置或替换某个扩展属性的值,或者创建一个新的扩展属性,成功执行时返回0;失败时返回相应的错误码。其定义在fs/xattr.c中,函数头如下所示:

static long(struct*, const char*, const void*,

, int)

如上所示,该函数包含五个参数:d指向目标对象对应的目录项;name表示用户空间的扩展属性名;value表示用户空间的扩展属性的值;size表示扩展属性值的长度;flags表示传递给文件系统相关操作的标志。

933506db36bc4659fadc5487f5deba12.png

图2-2 setxattr()函数调用流程图

如图2-2所示,下面结合源码对该函数的执行步骤进行说明:

① 对参数的合法性进行检查。

② 分别调用strncpy_from_user()函数和copy_from_user()函数将参数从用户空间拷贝到内核空间中。

③ 调用vfs_setxattr()函数来实现扩展属性的相关具体操作,对于该函数,下文会进行详细分析。

④ 结束并返回。

对于vfs_setxattr()函数,其定义在fs/xattr.c中,函数头如下所示:

int(struct*, const char *, const void *,,

int)

该函数包含5个参数,参数含义和setxattr()的参数含义基本相同,这里不再赘述。对于该函数,其函数调用流程如图2-3所示,下面结合源码对该函数的执行步骤进行说明:

① 调用xattr_permission()函数来检查用户对指定的文件是否具有写权限,如果有,则返回0,如果没有,vfs_setxattr()函数将会直接返回。

② 调用security_inode_setxattr()函数。该函数实际上只是简单的封装了cap_inode_setxattr()函数,后者用于确定当前进程是否具有修改指定文件扩展属性的权限,若有,则返回0。

③ 如果当前进程可以修改文件的扩展属性,则调用__vfs_setxattr_noperm()函数,该函数在不进行权限检查的情况下执行具体文件系统实现的setxattr()函数来对目标文件的扩展属性进行设置。

④ 结束并返回。

a2f928f5bc0dac96aa0f83135c7d6a36.png

图2-3 vfs_setxattr()函数调用流程图

对于vfs_setxattr()函数调用的两个函数xattr_permission()和__vfs_setxattr_noperm(),下面分别对其进行分析:

1. xattr_permission()

xattr_permission()函数用于判断用户是否可以对指定文件执行指定的操作,若可以,返回0。由于该函数只是根据扩展属性所属的命名空间进行不同的处理,其处理过程比较简单,所以这里直接对其处理过程说明如下:

① 对参数进行判断,如果要对不可修改为文件或只能追加的文件进行写操作,则函数直接返回-EPERM。

② 判断扩展属性是否位于security或system命名空间,若是,则VFS不对其进行限制,而是将扩展属性的判断留给底层文件系统或安全模块,这里直接返回0。

③ 判断扩展属性是否位于trust命名空间,若是,则只有特权用户才能进行访问。

④ 判断扩展属性是否位于user命名空间,若是,则按下述步骤进行处理:

a.判断待访问的文件是否是普通文件或目录,因为只有普通文件和目录才具有扩展属性,若不是,则返回相应的错误码。

b.判断待访问的文件是否是目录、“粘着位”是否置位、当前进程是否是目录的所有者或是由特权用户触发的,并根据判断结果进行相应处理。因为对于“粘着位”置位的目录来说,只有所有者和特权用户才能写入属性。

⑤ 调用inode_permission()函数来判断当前进程对待处理的文件是否具有mask指定的权限,并返回该函数的执行结果。对于该函数的详细分析,详见2.3.4.1小节。

⑥ 结束。

2. __vfs_setxattr_noperm()

__vfs_setxattr_noperm()函数用于在不进行权限检查的情况下执行setxattr操作,函数头如下所示:

int(struct*, const char *,const void *,

,int)

该函数包含5个参数,各参数含义和setxattr()的参数含义基本相同,这里不再赘述。

197f1b18d68dfee3f102c54a32ba4300.png

图2-4 __vfs_setxattr_noperm()函数调用流程图

如图2-4所示,下面结合源码对该函数的执行步骤进行说明:

① 判断要设置的扩展属性是否位于security命名空间,若是,则将issec设为0;反之设为1。

② 判断索引节点所属的文件系统是否实现了setxattr()方法。如果实现,则调用该方法,并对函数执行结果进行判断,如果函数成功执行,则采用inotify机制通知父目录该文件的扩展属性发生变化。

③ 如果索引节点所属的文件系统没有实现setxattr()函数,则接着判断issec变量。如果该变量为真,即指定的扩展属性在security命名空间中,则调用security_inode_setsecurity()函数来进行扩展属性的设置,该函数实际上是由LSM机制提供的,视具体的安全策略而设zhi置。如果其成功执行,则调用inotify机制通知父目录。

④ 结束并返回。

责任编辑:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值