什么是SELinux

SELinux 即Security-Enhanced Linux, 是一套强制性安全审查机制,Linux Kernel 2.6 版本后, 有直接整合进入SELinux, 搭建在Linux Security Module(LSM)基础上

SELinux 基本架构与原理.

SELinux 是典型的MAC-Mandatory Access Controls 实现, 对系统中每个对象都生成一个安全上下文(Security Context), 每一个对象访问系统的资源都要进行安全上下文审查。审查的规则包括类型强制检测(type enforcement), 多层安全审查(Multi-Level Security), 以及基于角色的访问控制(RBAC: Role Based Access Control).

SELinux 搭建在Linux Security Module(LSM)基础上,关于 LSM 架构的详细描述请参见文章 “Linux Security Modules: General Security Support for the Linux Kernel”, 该文章在 2002 年的 USENIX Security 会议上发表。有完整的实现LSM 的所有hook function.
SELinux 的整体结构如下图所示:

SELinux 包含五个基本组成:

  • 用于处理文件系统的辅助模块, 即SELinuxFS.
  • 集成Linux Security Modules 的hooks sets.
  • Security Policy Database.
  • Security Label 验证模块.
  • Access Vector Cache (AVC), 访问向量缓存,以便提高验证速度.

基本的访问流程如下图所示:

流程如下:

  • 进程通过系统调用(System Call) 访问某个资源, 进入Kernel 后, 先会做基本的检测, 如果异常则直接返回.
  • Linux Kernel DAC 审查, 如果异常则直接返回.
  • 调用Linux Kernel Modules 的相关hooks, 对接到SELinux 的hooks, 进而进行MAC 验证, 如果异常则直接返回.
  • 访问真正的系统资源.
  • 返回用户态, 将结构反馈.

DAC(Discretionary Access Control):自主访问控制,基于“用户-用户组-其他/读-写-执行”的权限检查,进程理论上所拥有的权限与执行它的 用户的权限相同,该管理过于宽松,如果获得 root 权限,可以在 Linux 系统内做任何事情。
MAC(Mandatory Access Control):强制访问控制,基于安全上下文和安全策略的安全机制,用于补充 DAC 检查。访问系统资源时,会先进行 DAC 检查,DAC 检查通过,才能进行 MAC 检查,如果 MAC 检查通过,才能获得资源访问权限。SELinux 是 MAC 机制的一种实现

Core SELinux Components

SELinux 的核心组件可以参考下面的图:

  • Subject 通常是指触发访问行为的对象, 在Linux 里面通常是一个进程(Process).
  • Object Manager 即是对象访问管理器, 即可以知道Subject 需要访问哪些资源,并且触发验证机制
  • Security Server 即安全服务器, 用来验证某个Subject 是否可以真正的访问某个Object, 而这个验证机制是基于定义好的Security Policy.
  • Security Policy 是一种描述SELinux Policy 的语言.
  • Access Vector Cache (AVC) 是访问缓存, 用来记录以往的访问验证情况, 以便提供效率,快速处理.
审查机制

SELinux 对MAC支持两种机制:

  • Type Enforcement (TE)
    顾名思义, Type Enforcement 是根据Security Label 中的 type 进行权限审查, 审查 subject type 对 object type 的某个class 类型中某种permission 是否具有访问权限,是目前使用最为广泛的MAC 审查机制, 简单易用。

  • Multi-Level Security (MLS)
    多层安全机制, 是基于Bell-La Padula (BLP) 模型, 将Subject 和 Object 定义成多层次的安全等级, 不同安全等级之间有相关的访问约束, 常见的访问约束是 “no write down” 和 “no read up”. 它是根据Security Label 里面的最后一个字段label 进行确认的.
    目前在Android 中,重点启用了Type Enforcement 机制.

TE中控制语句的格式:rule_name source_type target_type : class perm_set

  • rule: 控制类型, 分成两方面 allow 以及 audit
  • source_type:也叫subject,通常是domain。
  • Target_type: 代表请求的资源的类型
  • class perm_set: 代表对资源访问的操作

TE中的rule:

  • allow:赋予某项权限。
  • auditallow:audit含义就是记录某项操作。默认SELinux只记录那些权限检查失败的操作。 auditallow则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使用allow语句。
  • dontaudit:对那些权限检查失败的操作不做记录。
  • neverallow:用来检查安全策略文件中是否有违反该项规则的allow语句

举个栗子:下面是谷歌原生策略中init.te中的一部分

# Create /data/property and files within it.
allow init property_data_file:dir create_dir_perms;
allow init property_data_file:file create_file_perms;# Set any property.
allow init property_type:property_service set;# init can only find the APEX service
neverallow init { service_manager_type -apex_service }:service_manager { find };
# init can never add binder services
neverallow init service_manager_type:service_manager { add };
# init can never list binder services
neverallow init servicemanager:service_manager list;
Security Context

SELinux 给Linux 的所有对象都分配一个安全上下文(Security Context), 描述成一个标准的字符串。
两种类型

  • Subject 主体, linux通常以进程为单位
  • Object 访问对象, linux 通常以文件为单位
    标准格式
    user:role:type:[range]
  • User: 用户, 非Linux UID。android 只定义了一个user u
  • Role: 角色,一个user可以属于多个role,不同的role具有不同的权限。它是SELinux中一种比较高层次,更方便的权限管理思路,即Role Based Access Control(基于角色的访问控制,简称为RBAC, SELinux 不推荐使用)。android 只定义了一个role r,以及file system 使用object_r。因为user u 只有一个 role r, 所以没有进行角色访问约束(RBAC)。
  • Type: Subject或者Object的类型。 MAC的基础管理思路其实不是针对上面的RBAC,而是所谓的Type Enforcement Access Control(简称TEAC,一般用TE表示:根据Security Label 中的 type 进行权限审查, 审查 subject type 对 object type 的某个class 类型中某种permission 是否具有访问权限)。对进程来说,Type就是Domain。
  • Range: Multi-Level Security(MLS)的级别。MLS将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问。

如何查看文件的SELinux Context:ls -lZ

如何查看进程的SELinux Context: ps -Z 或者cat proc/PID/attr/current, 查看当前进程可用id

也可以使用ps -AZ,查看所有进程。

SELinux Mode

SELinux 分成两种模式, 即Permissve Mode(宽容模式), 和 Enfocing mode(强制模式).
Permissive Mode 只通过Kernel Audit System 记录LOG, 但不真正拦截访问.
Enforcing Mode 在记录LOG 的同时,还会真正的拦截访问.

查看SELinux 模式

  • 使用命令: adb shell getenforce
  • 通过AVC log 查看,在log结尾有 permissive=1/0 的标示: 1表示Permissive, 0表示Enforcing

切换SELinux模式

  • 使用命令: adb root; adb shell setenforce 0 (0表示Permissive模式, 1表示Enforcing模式),重启后失效
  • 修改init:修改system/core/init/SELinux.cpp文件里的IsEnforcing()函数,将该函数直接返回false

AVC log:
0181D <5> [ 94.720314][01-21 11:16:38.720] audit: type=1400 audit(1611198999.579:468): avc: denied { read } for pid=3949 comm=“ww6.temperature” name=“calibration” dev=“sysfs” ino=20396 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0
ww6.temperature 进程缺少对标签为sysfs,类型为file,名称为calibration文件的 read权限

0057D <11> [ 2.746412][12-31 19:05:22.746] selinux: avc: denied { set } for property=ro.sf.lcd_width pid=1 uid=0 gid=0 scontext=u:r:vendor_init:s0 tcontext=u:object_r:default_prop:s0 tclass=property_service permissive=0\x0a

AVC log说明:

  • <5> : kernel log level
  • [ 94.720314] [01-21 11:16:38.720]: kernel time
  • audit: log TAG 表示此log是通过audit打印的
  • type=1400: SYSCALL type=AVC - for kernel events type=USER_AVC - for user-space object manager events
  • audit(1611198999.579:468):audit(time:serial_number)
  • avc: denied: 表示当前操作被拒绝
  • { read } : 表示被拒绝的操作,{}中含有实际尝试的操作
  • for pid=3949 : 表示被拒的是一个进程,进程ID 3949
  • comm=“ww6.temperature” : 发生avc:denied的进程的进程名,即主体进程名
  • name=“calibration”: 尝试操作的目标文件或者目录的路径,即客体资源名称
  • dev=“sysfs” : 含有这个文件系统的设备节点,客体资源在该文件系统中
  • ino=20396 : 目标文件或目录的节点号
  • scontext=u:r:untrusted_app:s0 : 主体进程的安全上下文(例子中多了一个’:c512,c768’,说明了主体和客体安全级别不同(MLS规则))
  • tcontext=u:object_r:sysfs:s0: 客体资源的安全上下文
  • tclass=file:访问资源所属类别
  • permissive=0:当前是 Enforcing 模式,permissive=1 时为 Permissive 模式
SELinux 策略

SELinux 策略类型:(由于system image和vendor image的分离导致有了sepolicy的分离)

  • Public 公共策略(基础部分):导出的策略是非平台策略,开发人员可以在该策略上编写附加策略。类型和属性被版本化的策略包含在已交付的非平台策略中,非平台策略将与平台策略组合在一起。(定义的类型和属性system和vendor都可以使用)
  • Private 私有策略(基础部分):平台功能需要的策略,不会导出给其他供应商策略开发人员,因此可以假定不存在。(仅system image内部使用,只会编译到system image)
  • Vendor 供应商通用组件策略(外扩组件部分):供应商功能需要“仅供应商策略”。该政策可以参考公共政策,但不能参考私人政策。此策略适用于从核心/非供应商树生成并放置到供应商分区的组件。(只会编译到vendor image,能够引用到public目录下的定义并设置策略)

谷歌原生策略:

  • /system/sepolicy:谷歌原生策略,不要在此路径下进行修改
  • /system/sepolicy/private:谷歌原生 system 分区 private sepolicy
  • /system/sepolicy/public:谷歌原生 system 分区 public sepolicy
  • /system/sepolicy/vendor:谷歌原生 vendor 分区 sepolicy
  • /system/sepolicy/prebuilts:版本兼容 sepolicy

谷歌原生策略不能修改,我们可以修改平台的补充策略,各个平台策略存放位置有所不同。

问题实践

尝试解决上述avc log报出的权限问题:

  1. 在哪儿修改呢?
    scontext=u:r:untrusted_app:s0: log中主体进程上下文告诉了我们,因此我们应该要去修改untrusted_app.te(可以使用find命令查找一下,应该会出现很多,这时候我们要考虑修改哪个目录下的)
  2. 怎么修改?
    格式:allow scontext tcontext:tclass permission;
    allow untrusted_app sysfs:file {read open};
  3. 编译验证
    模块编译:mmm system/sepolicy/
    编译后会在out目录下生成两个目录:
    \vendor\etc\selinux
    \system\etc\selinux
    将这两个目录push到设备中重启后生效

编译验证时编译报错了:

libsepol.report_failure: neverallow on line 91 of system/sepolicy/private/coredomain.te (or line 32356 of policy.conf) violated by allow untrusted_app sysfs:file { read write open };
libsepol.report_failure: neverallow on line 95 of system/sepolicy/private/app_neverallows.te (or line 29605 of policy.conf) violated by allow untrusted_app sysfs:file { read write open };
libsepol.report_failure: neverallow on line 92 of system/sepolicy/private/app_neverallows.te (or line 29586 of policy.conf) violated by allow untrusted_app sysfs:file { write };
libsepol.report_failure: neverallow on line 514 of system/sepolicy/public/app.te (or line 9547 of policy.conf) violated by allow untrusted_app sysfs:file { write };
libsepol.check_assertions: 4 neverallow failures occurred

报错原因是被google用neverallow禁止了。Google 默认禁止app , 包括system app, radio app 等直接写/sys 目录以u:object_r:sysfs:s0 为标签的文件以及/proc 目录以u:object_r:proc:s0文件。如果直接放开SELinux 权限, 会导致CTS 无法通过

如何处理与Google 定义neverallow 冲突

当我们的权限被neverallow 后,我们不能直接去删掉neverallow ,会导致CTS无法通过,因此我们只能绕道,两种方式:

  • 通过system server service 或者 init 启动的service 读写操作, 然后app 通过binder/socket 等方式连接APP 访问. 此类安全可靠, 并且可以在service 中做相关的安全审查
  • 修改对应节点的SELinux Security Label, 为特定的APP,具体做法(以上述AVC报错为栗子):
    1. 参考原来的 sysfs 类型(type sysfs, fs_type, sysfs_type, mlstrustedobject;)定义一种新 type,
      在file.te中添加:type sysfs_xxx, fs_type, sysfs_type, mlstrustedobject;
    2. 使用新定义的 type 为目标文件配置安全上下文
      在file_context中添加:/xxx/xxx (目标文件路径) u:object_r:sysfs_xxx:s0
    3. 重新赋予主体进程访问新类型文件的权限
      在untrusted_app.te中添加:allow untrusted_app sysfs_xxx:file {read open};
新增属性配置安全上下文

Android 属性 property 在系统中存放在一块共享内存中,每个进程都能读,但是只有 init 进程能够写,请
求 init 进程帮助写属性值是需要 SELinux 权限的。
Android 属性名称前缀必须用 system\core\init\property_service.c 中定义的:

  • vendor 属性名前缀
  • persist.vendor.**
  • vendor.**
  • ro.vendor.**
    属性名不包含 vendor,则为系统属性。
    Android 11.0 属性标签有了更严格的限制,在 vendor 域属性所打的标签必须以 vendor_开头,否则会导致
    vts 测试失败。
    根据属性的命名规范,选择定义在 system 分区还是 vendor 分区,以 vendor 为例,新增属性步骤如下:
  1. 在 property.te 中添加属性的 type 定义。
    type vendor_xxx_prop, property_type;
  2. property_contexts 中对属性设定安全上下文。
    xxx.xxx. u:object_r:vendor_xxx_prop:s0
    xxx.xxx 后的“.”表示匹配以 xxx.xxx 开头的属性。
  3. xxx.te 文件中赋予对应进程访问该类型属性的权利。
    set_prop(xxx, vendor_xxx_prop)

SELinux 学习总结相关推荐

  1. linux lsm 程序加载钩函数,selinux 学习笔记一(LSM在kernel中的实现)

    LSM(linux security module)作为一个单独模块,通过在kernel编译过程中的编译flag:CONFIG_SECURITY 控制是否启用该模块中定义的安全相关的功能.具体配置信息 ...

  2. redhat安装配置Apache服务

    一.常用的安装和管理命令 yum install httpd #安装Apache,也就是httpd服务 systemctl start httpd #启动httpd服务 systemctl enabl ...

  3. Linux学习之CentOS(三十)--SELinux安全系统基础

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  4. SELinux零知识学习四、Audit应用层源码下载、编译和安装

    接前一篇文章:SELinux零知识学习三.SELinux应用层源码下载.编译和安装 在前篇文章中编译SELinux源码时,出现了如下错误: seusers_local.c:11:10: 致命错误:li ...

  5. SELinux零知识学习六、swig源码下载、编译和安装

    接前一篇文章:SELinux零知识学习五.libcap-ng源码下载.编译和安装 在前篇文章中编译libcap-ng源码时,出现了如下错误: swig -o capng_wrap.c -python ...

  6. Linux的基本学习(十四)——进程管理(下)与SELinux

    Linux的基本学习(十四)--进程管理(下)与SELinux 前言 进程这部分内容真是不少,来,我们继续跟着鸟哥学习. 特殊文件与进程 具有SUID/SGID权限的命令执行状态 SUID的权限其实与 ...

  7. Hadoop学习之虚拟机环境配置,防火墙、selinux关闭、集群时间同步(LinuxcentOS7版本)

    目录​​​​​​​ 1. 镜像文件下载 2.Linux-centOS安装 第三步与第三步需在root用户下进行操作 3.虚拟机关闭防火墙 4.设置selinux 5.集群时间同步 1. 镜像文件下载 ...

  8. linux系统盘的概念,了解linux系统硬盘分区概念-SELinux入门-linux网卡配置及参数学习_169IT.COM...

    几乎可以肯定每个人都听说过 SELinux (更准确的说,尝试关闭过),甚至某些过往的经验让您对 SELinux 产生了偏见.不过随着日益增长的0-day 安全漏洞,或许现在是时候去了解下这个在 Li ...

  9. SELinux的学习

    SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security Agency」 和SCC(Secure Computin ...

最新文章

  1. arm remapping控制输入_解析机器视觉中运动控制卡与PLC的区别
  2. Android杂谈--layout的横竖屏处理
  3. YARN/MRv2 Resource Manager深入剖析—RM总体架构
  4. 【学术相关】近5年十大最具影响力的 AI 论文,你知道几个?
  5. Lesson 31-32 Personal Habits
  6. CodeForces - 1509C The Sports Festival(dp)
  7. python字符子串_子字符串和子序列(Python),子串,python
  8. VC“cannot execute program”错误的解决方法
  9. poj 3384 Feng Shui (Half Plane Intersection)
  10. 面经——Linux使用
  11. Docker安装nginx以及负载均衡
  12. CWMP\TR069协议学习随笔1——入门基础知识及环境搭建
  13. 苹果和亚马逊因疑似侵犯云端同步功能专利而被提起美国337调查
  14. 粗识计算机--Java学习Day01
  15. 360 极速模式 html,360浏览器极速模式怎么开
  16. Planner – 项目管理软件 - 小众软件
  17. json datasource使用
  18. 如何科学管理你的密码
  19. 数据集处理(三)——打乱数据集
  20. python实例-银行管理系统(特简单的那种)

热门文章

  1. 图书管理系统(纯C语言)
  2. 最近笔记本电脑开机启动正常,进入黑屏?
  3. ​网易游戏实时 HTAP 计费风控平台建设
  4. 中国信息安全测评中心-自主原创测评
  5. 使用注解失败的原因及解决方法
  6. 《那些年啊,那些事——一个程序员的奋斗史》——40
  7. NOIP2014、2015普及组初赛难点整理
  8. IPC网络摄像机NTP校时 时间无法同步问题排查
  9. mysql查询IN索引无效的问题【已解决】
  10. 数据结构与算法--散列表