3.决策的实施

当主体对客体进行访问时,客体管理器会收集主体和客体的SID,并根据此SID对在AVC中进行查找:如果找到,则根据相应的安全决策进行处理;反之客体管理器会将主体的SID、客体的SID以及客体的类型传递给安全服务器,安全服务器会根据这些数据及相应的安全策略来计算访问向量,并将计算结果返回给客体管理器,同时将该结果存放到AVC。本节主要以文件系统为例说明文件访问时决策的检索过程,文件操作分为三步:打开、读写、关闭,下面依次从文件的打开及读写的角度从源码上对决策的检索过程进行分析。

(1)文件的打开

在Linux中,当对文件进行操作时,首先需使用open()系统调用打开该文件,在使用open()系统调用打开要访问的文件时就需要检查主体是否有权限访问指定的文件。

图2-23 打开文件时权限的检查过程调用图

如图2-23所示,其中灰色背景标注的红色文字为inode操作集中相应的文件创建时调用的钩子函数,在ext4文件系统中,该钩子函数对应的回调函数为ext4_create()。open()系统调用经过层层调用,最后会通过inode_permission()函数来检查指定inode的访问权限,该函数首先基于ACL进行权限的检查,接着检查主体是否能访问文件所在的设备,最后调用security_inode_permission()函数基于挂载到LSM的安全策略来进行权限的检查。对于inode_permission()函数,详细介绍详见“Linux自主访问控制机制模块代码分析报告”一文,这里不再赘述,下面主要针对security_inode_permission()函数进行详细分析。

security_inode_permission()函数用于通过挂载到LSM的安全策略模块来对文件的访问权限进行检查,以判断某一主体是否可以访问指定的文件,其代码如下所示:

intsecurity_inode_permission(structinode*inode, intmask)

该函数包含两个参数:inode表示要访问的文件的inode;mask表示要检查的权限掩码。对于该函数,其首先判断指定的inode是否是文件系统私有的inode,若是则函数直接返回0;反之调用LSM的钩子函数inode_permission()来进行权限的检查。在启用了SELinux的系统中,security_ops变量指向SELinux实现的相关函数,此时inode_permission()钩子即对应selinux_inode_permission()函数。selinux_inode_permission()函数用于在主体访问inode之前检查其是否具有相应的权限,成功时返回0,该函数定义在security/selinux/hooks.c中,函数头如下所示:

static intselinux_inode_permission(structinode*inode, intmask)

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

①判断待检查的权限mask是否设置了读、写、执行或追加权限,如果没有,则说明不需要进行权限的检查,此时函数直接返回0。

②调用validate_creds()函数验证当前进程的cred是否有效。若无效,则通知使用了无效的凭证。

③调用IS_PRIVATE()宏判断指定的inode是否是文件系统内部的inode,若是,则直接返回0。

④调用file_mask_to_av()函数将linux中文件的类型和权限转化为访问向量。

⑤调用cred_sid()函数获取当前进程的SID。

⑥调用avc_has_perm_noaudit()函数进行权限的检查,对于该函数,详细分析参见3.1节。

⑦调用avc_audit_required()函数计算待审计的权限及拒绝的权限,并返回待审计的权限。

⑧判断是否存在要审计的权限,如果不存在待审的权限,则函数返回。

⑨调用audit_inode_permission()函数来审计相应的权限。该函数封装了slow_avc_audit()函数,后者最终会调用common_lsm_audit()函数。common_lsm_aduit()函数是一个通用的lsm审计函数,它根据普通的安全信息设置审计缓冲区,并调用回调函数来打印LSM指定的信息。对于其详细介绍,参见“Linux安全审计机制模块代码分析报告”一文。

⑩结束并返回。

图2-24 selinux_inode_permission()函数调用流程图

(2)文件的读写

当使用open()系统调用打开文件后,此时即可使用read()/write()系统调用来对该文件进行读写操作,在使用read()/write()系统调用读写打开的文件时就需要检查主体是否有权限读写指定的文件。对于该过程,函数调用过程如图2-25所示:

图2-25文件读写时权限检查的过程调用图

如上图所示,read()/write()系统调用经过层层调用,最后均会通过security_file_permission()函数来检查指定inode的访问权限,该函数定义在security/security.c中,代码如下所示:

intsecurity_file_permission(structfile*file, intmask)

{

intret;

ret=security_ops->file_permission(file,mask);

if (ret)

returnret;

returnfsnotify_perm(file,mask);

}

该函数包含两个参数:file表示进程打开的文件;mask表示要检查的权限掩码。对于该函数,其首先调用LSM的钩子函数file_permission()在访问打开的文件之前进行权限的检查,如果安全模块授予了相应的权限,则调用fsnotify_perm()函数来通知父目录对该文件进行了相应的操作,对于该函数,详细介绍参见“Linux完整性保护机制模块代码分析报告”一文;反之直接返回。对于启用了SELinux的系统来说,LSM的file_permission()钩子对应的回调函数为selinux_file_permission(),其代码如下所示:

static intselinux_file_permission(structfile*file, intmask)

{

structinode*inode=file->f_path.dentry->d_inode;

structfile_security_struct*fsec=file->f_security;

structinode_security_struct*isec=inode->i_security;

u32sid=current_sid();

if (!mask)

return 0;

if (sid==fsec->sid&&fsec->isid==isec->sid&&

fsec->pseqno==avc_policy_seqno())

return 0;

returnselinux_revalidate_file_permission(file,mask);

}

如上所示,该函数包含两个参数,其含义和security_file_permission()函数相同,这里不再赘述。该函数首先对参数进行相应的检查,如果通过了检查,则调用selinux_revalidate_file_permission()函数,selinux_revalidate_file_permission()函数只是对file_has_perm()函数的简单封装,因此下文主要针对file_has_perm()函数进行详细的分析。

file_has_perm()函数用于检查一个进程是否可以使用打开的文件描述符以指定的方式来访问一个inode,其定义在security/selinux/hooks.c中,函数头如下所示:

static intfile_has_perm(const structcred*cred,structfile*file,u32av)

该函数包含3个参数:cred表示相应的进程的凭证;file表示要访问的文件对应的打开的文件描述符;av表示相应的访问向量。对于该函数,其函数调用流程如图2-26所示,下面结合源码对该函数的执行步骤进行说明:

①调用cred_sid()函数获取当前进程的SID。

②判断当前进程的SID是否与打开的文件描述符的SID相等,若不等,则调用avc_has_perm()函数来进行权限的检查,对于其详细的介绍,参见2.3.2.1小节。

③判断av是否为空,若不为空,则调用inode_has_perm()检查指定的进程对指定节点是否具有参数av指定的权限。

④结束并返回。

图2-26 file_has_perm()函数调用流程图

linux 对象管理器,Linux多安全策略和动态安全策略框架模块详细分析之函数实现机制中文件对象管理器分析(3)...相关推荐

  1. linux注册函数机制,Linux可信计算机制模块详细分析之函数实现机制(1)字符设备驱动...

    原标题:Linux可信计算机制模块详细分析之函数实现机制(1)字符设备驱动 2.3 函数实现机制 2.3.1 Linux 字符设备驱动 在linux 3.5.4中,用结构体cdev描述字符设备,cde ...

  2. linux安全策略查询代码,Linux多安全策略和动态安全策略框架模块代码分析报告(14)...

    函数名称 函数功能 selinux_set_mapping() 计算参数map中客体类别的数量,并将map中字符形式的类别-权限映射转换为数值形式的类别权限映射 map_class() 将客体类别在策 ...

  3. Linux 静态库和共享(动态)库的创建与使用详解

    文章目录 Linux 静态库和共享(动态)库 库的介绍 使用库有什么好处 库制作完成后, 如何给用户使用 静态库(static library) 静态库的制作 ar工具创建lib过程 静态库的使用 源 ...

  4. Linux桌面需要强制访问控制,Linux强制访问控制机制模块详细描述(1)

    原标题:Linux强制访问控制机制模块详细描述(1) 2 详细分析 2.1模块功能描述 对于SELinux中实现的MLS,其主要通过安全级别对系统资源的访问进行限制,相关操作定义在security/s ...

  5. 【Android 逆向】arm 汇编 ( 使用 IDA 解析 arm 架构的动态库文件 | 分析 malloc 函数的 arm 汇编语言 )

    文章目录 一.分析 malloc 函数的 arm 汇编语言 一.分析 malloc 函数的 arm 汇编语言 在上一篇博客 [Android 逆向]arm 汇编 ( 使用 IDA 解析 arm 架构的 ...

  6. Linux服务器安全策略配置-PAM身份验证模块(二)

    ○ 本文导航 关于PAM PAM身份验证配置文件 PAM配置文件语法格式 PAM模块接口 PAM控制标志 PAM配置方法 PAM身份验证安全配置实例 - 强制使用强密码(用户密码安全配置) - 用户S ...

  7. linux内核采取,采用动态加载模块的方式Linux内核编译

    Linux内核是一种单体内核,但是通过动态加载模块的方式,使它的开发非常灵活方便.那么,它是如何编译内核的呢?我们可以通过分析它的Makefile入手.以下是一个简单的hello内核模块的Makefi ...

  8. Linux下的静态库、动态库和动态加载库

    from: http://www.techug.com/linux-static-lib-dynamic-lib 库的存在极大的提高了C/C++程序的复用性,但是库对于初学者来说有些难以驾驭,本文从L ...

  9. linux 动态链接库的创建和使用--动态连接

    linux 动态链接库的创建和使用--动态连接 分类: C 编程 2012-03-25 17:01 568人阅读 评论(0) 收藏 举报 linuxreferencefunctiondatec /* ...

最新文章

  1. Linux下安装Python-3.3.2【转】
  2. 转:A/B测试:实现方法
  3. 工程设计论——如何写好工程代码
  4. 别人家的公司!雷军发红包 人均39万
  5. Docker 基础介绍及配置安装 [一]
  6. SignalR 服务器系统配置要求
  7. asp.net mysql数据库连接字符串_如何让您的ASP.NET数据库连接字符串是安全的
  8. 深入理解函数中分配内存的问题
  9. 阿里云三件“法宝”帮助企业应对未来的互联网挑战
  10. MapStruct 详解
  11. 150页的剑指Offer解答PDF,它来了!!!
  12. 银行信贷系统java_java毕业设计_springboot框架的银行信贷系统
  13. HDU 6287 口算训练 (质因数分解)
  14. tomcat上部署的solr的移植以及数据的备份与恢复
  15. 游戏图片文件和声音文件的隐藏
  16. AWS免费套餐服务器部署NETCORE网站
  17. 2021-12-17 每日一练 100元怎么买100个蛋,鸡蛋1毛一个,鸭蛋3元一个,鹅蛋6元一个
  18. key 、primary key 、unique key 与index区别
  19. “不务正业”的美图公司也是一名“赌徒”
  20. **rosdep init** 或者**rosdep update** 连接错误的解决办法

热门文章

  1. python判断是否为变位词_python实现对变位词的判断方法
  2. python职业发展方向_测试的职业发展方向有哪些?该如何规划?
  3. w3c+html+格式转换,HTML 转义字符
  4. mysql query sql_sql:query 标签
  5. firebird 3.0 开发者指南_11月19日召开 2020 vivo开发者大会报名正式开启
  6. 知乎超热门话题:为什么要考985?
  7. php导入关系表,PHP导入Execl表到数据库
  8. linux oracle 01157,Oracle数据库启动时出现ORA-01157和ORA-01110问题
  9. FTPClient登录慢的问题
  10. pipline中替换tag变量