2详细分析2.1模块功能描述访问控制列表ACL主要用于提供传统的owner、group、others的read、write、execute之外的具体权限设置,它可以针对单一用户、单一文件或目录进行权限的设置,从而细化权限的管理。2.2模块内部函数调用关系
图2-1 模块内函数之间的调用关系 如图2-1所示,当用户程序需要访问文件时,便会调用相应的系统调用如open(),该系统调用在执行时会通过系统调用服务例程陷入内核,然后调用VFS中相关操作对该请求进行处理,最后当要访问文件对应的内核数据时,内核会先检查该用户是否具有访问权限,如果权限检查通过,此时才能真正访问相应的数据,否则拒绝用户的请求。在进行权限检查时,依次会进行普通的权限检查、DAC检查和MAC检查,如果所有的检查均通过则允许用户访问该文件。在进行DAC检查时,VFS会根据用户请求的文件的类型来调用相应文件系统中实现的函数来从文件的扩展属性中查找文件的ACL权限,如果文件中指定了相应的权限,则检查通过,否则函数直接返回,即拒绝用户的访问请求。 2.3函数实现机制 在Linux中,通过VFS来对所有的具体文件系统进行统一的管理,VFS通过向用户程序提供一套统一、标准的抽象接口来为用户程序提供标准的功能,进而向用户屏蔽具体文件系统的实现细节,然而这只能实现一些标准的操作,对于某些具体文件系统的某些特性,其并不能很好的支持,因为VFS不可能为它所能想到的所有特性都进行具体的实现。为了解决这个问题,Linux采用扩展属性来实现,每个文件都可以根据其需求来实现相应的扩展属性,从而将其与文件相关联。扩展属性在Linux中有两种用途:
/* Namespaces */ #define XATTR_OS2_PREFIX"os2." #define XATTR_OS2_PREFIX_LEN(sizeof (XATTR_OS2_PREFIX) - 1)
#define XATTR_SECURITY_PREFIX"security." #define XATTR_SECURITY_PREFIX_LEN(sizeof (XATTR_SECURITY_PREFIX) - 1)
#define XATTR_SYSTEM_PREFIX"system." #define XATTR_SYSTEM_PREFIX_LEN(sizeof (XATTR_SYSTEM_PREFIX) - 1)
#define XATTR_TRUSTED_PREFIX"trusted." #define XATTR_TRUSTED_PREFIX_LEN(sizeof (XATTR_TRUSTED_PREFIX) - 1)
#define XATTR_USER_PREFIX"user." #define XATTR_USER_PREFIX_LEN(sizeof (XATTR_USER_PREFIX) - 1) 为了操作扩展属性,内核提供了以下四个系统调用: (1) setxattr() 用于根据参数来设置或替换某个扩展属性的值,或者创建一个新的扩展属性 (2) getxattr() 用于获取指定扩展属性的值 (3) listxattr() 用于获取文件的扩展属性列表 (4) removexattr() 用于删除指定的扩展属性 对于上述函数,它们还有前缀为l和前缀为f的变体,前缀为l的变体用于对符号链接本身的扩展属性进行操作;前缀为f的变体用于对通过文件描述符指定的文件进行处理。对于这三种类型的系统调用,它们之间唯一的区别在于查找目标对象关联的dentry实例的方式,当找到目标对象对应的目录项之后,它们将会调用相同的函数来进行进一步的处理。下面主要针对setxattr()类系统调用进行分析,对于这些函数,在它们通过相应的方式获得目标对象对应的目录项之后,均会调用setxattr()函数进行进一步的处理。setxattr()函数真正用于根据参数来设置或替换某个扩展属性的值,或者创建一个新的扩展属性,成功执行时返回0;失败时返回相应的错误码。其定义在fs/xattr.c中,函数头如下所示: static longsetxattr(struct dentry*d, const char __user*name, const void __user*value, 图2-2 setxattr()函数调用流程图 如图2-2所示,下面结合源码对该函数的执行步骤进行说明: ①对参数的合法性进行检查。 ②分别调用strncpy_from_user()函数和copy_from_user()函数将参数从用户空间拷贝到内核空间中。 ③调用vfs_setxattr()函数来实现扩展属性的相关具体操作,对于该函数,下文会进行详细分析。 ④结束并返回。 对于vfs_setxattr()函数,其定义在fs/xattr.c中,函数头如下所示: intvfs_setxattr(struct dentry*dentry, const char *name, const void *value,size_tsize, int flags) 该函数包含5个参数,参数含义和setxattr()的参数含义基本相同,这里不再赘述。对于该函数,其函数调用流程如图2-3所示,下面结合源码对该函数的执行步骤进行说明: ①调用xattr_permission()函数来检查用户对指定的文件是否具有写权限,如果有,则返回0,如果没有,vfs_setxattr()函数将会直接返回。 ②调用security_inode_setxattr()函数。该函数实际上只是简单的封装了cap_inode_setxattr()函数,后者用于确定当前进程是否具有修改指定文件扩展属性的权限,若有,则返回0。 ③如果当前进程可以修改文件的扩展属性,则调用__vfs_setxattr_noperm()函数,该函数在不进行权限检查的情况下执行具体文件系统实现的setxattr()函数来对目标文件的扩展属性进行设置。 ④结束并返回。 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|