Android P SELinux (一) 基础概念
Android P SELinux (二) 开机初始化与策略文件编译过程
Android P SELinux (三) 权限检查原理与调试
Android P SELinux (四) CTS neverallow处理总结

在处理了一些SELinux相关的问题之后,深深厌恶这个东西,一打开就报一大堆权限问题,添加te权限还特别麻烦,第一次搞下来没有1-2天是不行的。
抽时间查阅相关资料后,结合理论知识和源码进行分析,随着在项目中不断处理了一些CTS neverallow的失败项,慢慢地对SELinux有了更深入的理解,接下来的内容将分别介绍基础概念、SELinux开机初始化、SELinux编译相关和实际案例分享,让大家对SELinux有更加深入的认识。
学习一个模块的东西,我更喜欢从实际的问题出发去探索,因为目标很明确,不会漫无目的地跟着博客或书籍作者的思路游走,过程中不断提出新的问题,从而剥开这个模块的层层面纱并解决我的疑问,在总结的时候记忆也会更加深刻。
困扰已久的几个问题:
- make sepolicy局部编译后替换生成的目录/vendor/etc/selinux/和/system/etc/selinux/到板子,没有生效;每次都得整包编译升级才行,为什么有些平台就可以,这不是Android原生的吗?
- 项目上遇到升级后第一次开机,会报SELinux权限问题导致功能异常,第二次开机及以后功能就正常了,这是为什么?
- 我们遇到很多SELinux权限问题添加了权限之后,如果违反了neverallow规则,直接修改neverallow规则去掉限制,这个做法没有问题吗?既然都可以干掉规则了,那打开SELinux的意义又在哪里呢?
- 添加一个脚本的时候,为什么要添加这么多个te(在android/device/xxxxx/common/sepolicy和android/system/sepolicy都要添加 xxx.te ),而有些平台并不需要这样,这又是为什么?
之前一直比较认同没有办法了,才得修改neverallow
既然没法遵守规则,那就废除规则?
直到看到这篇博客的时候,我才意识到是我的认知窄了
selinux常见neverallow项解决方法与常用命令
目录
一、必读文章
SELinux(Security Enhanced Linux)是一个Linux内核模块,也是Linux的一个安全子系统
SELinux主要作用: 最大限度地减小系统中服务进程可访问的资源(最小权限原则)
在网上浏览了很多关于SELinux的文章,分享一些文章:
- SELinux Google官方文档
- 深入理解SELinux SEAndroid(第一部分)
- 深入理解SELinux SEAndroid之二
- 深入理解SELinux SEAndroid(最后部分)
- SEAndroid安全机制简要介绍和学习计划
- SEAndroid安全机制框架分析
- SEAndroid安全机制中的文件安全上下文关联分析
- SEAndroid安全机制中的进程安全上下文关联分析
- SEAndroid安全机制对Android属性访问的保护分析
- SEAndroid安全机制对Binder IPC的保护分析
- android 8.1 安全机制 — SEAndroid & SELinux
- selinux源码分析
- SELinux 安全上下文
本文内容开始之前,还望阅读一遍上面大佬的文章,会有很大帮助~
二、DAC 和 MAC
正如很多文章都会提到的两个概念:DAC 和 MAC
DAC:Discretionary Access Control 自主访问控制

进程理论上所拥有的权限与执行它的用户的权限相同,只要获得root权限,几乎无所不能
比如上面的图片,user是没有权限写入test.txt的
但是可以获取root权限,接着就能写入了
MAC:Mandatory Access Control 强制访问控制
相比DAC,这里进程和文件都被打上了安全上下文,user在写入test.txt的时候,除了要拥有写权限,同时也要在规则库里面声明权限,才能正常写入。
任何进程想在 SELinux 系统上干任何事情,都必须在安全策略文件中赋予权限,凡是没有出现在安全策略文件中的权限都不拥有;即使你是root,也不一定拥有权限操作,这个并不能做到防御一切攻击,但是能将损失降到最小
更多详细的介绍可以看看上面大佬们文章,这里只是简单说说自己的理解
三、SELinux Policy规则
3.1 安全上下文(Security Context)
完整的 Security Context 字符串为:
user:role:type[:range]
SELinux给每一个文件、进程、属性、服务都给打上一个标签,叫安全上下文(Security Context)
用下面的命令可以分别查看对应的安全上下文
- id -Z 查看当前进程的scontext
console:/ $ id -Z
context=u:r:shell:s0
console:/ # id -Z
context=u:r:su:s0
- ls -Z 查看文件的scontext
console:/ # ls -Z /data/property/persistent_properties
u:object_r:property_data_file:s0 /data/property/persistent_properties
- ps -AZ 查看所有进程的scontext
console:/ # ps -AZ | grep surface
u:r:surfaceflinger:s0 system 2930 1 67104 12856 SyS_epoll_wait 0 S surfaceflinger
- getprop -Z 查看属性的scontext
console:/ # getprop -Z | grep selinux
[ro.boot.selinux]: [u:object_r:default_prop:s0]
[ro.boottime.init.selinux]: [u:object_r:boottime_prop:s0]
[selinux.restorecon_recursive]: [u:object_r:restorecon_prop:s0]
- user:用户,Android里面就一个 u
- role:角色,进程用 r ,文件用 object_r
- type :类型,对进程而言也通常叫域,都是一个概念
- range,也就是上面的s0,是Multi-Level Security(MLS)的等级,这个有个概念就行了,MLS 将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问
安全上下文其实就是一个字符串,我们最需要关注的就是type,MAC基本管理单位是TEAC(Type Enforcement Accesc Control)
3.2 TE (Type Enforcement)
3.2.1 SELinux策略规则语句格式
rules domains types:classes permissions;
- rules 包括的规则有四个:allow、neverallow、dontaudit、auditallow
allow : 允许主体对客体进行操作
neverallow :拒绝主体对客体进行操作
dontaudit : 表示不记录某条违反规则的决策信息
auditallow :记录某项决策信息,通常 SElinux 只记录失败的信息,应用这条规则后会记录成功的决策信息 - domains 一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型
- types 一个对象(例如:文件、属性)或一组对象的标签
- classes 要访问的对象(例如:文件、属性)的类型
- permissions 要执行的操作(例如:读、写)
规则库以白名单的形式存在,要求所有允许的操作都必须要用allow规则来定义,不然都会被禁止操作
domains、types、classes、permissions都可以是单独的一个,也可以是一个集合,用花括号括起来
其中的domains和types,既可以指定一个type,也可以指定一组type(也就是attribute),这些定义在te文件里面
classes的定义在/android/system/sepolicy/private/security_classes
permissions的定义在/android/system/sepolicy/private/access_vectors
上面这些规则我们用最多的就是allow和neverallow,搞清楚这两个之后其他的规则是一样的道理
3.2.2 type和attribute
1、type的定义规则
type type_name [alias alias_set] [, attribute_set] ;
比如system_app.te里面定义:
type system_app, domain;
type的名字是system_app
alias定义的是别名,在Android里面这个基本没有用到,见不到它的身影
逗号后面的是属性(attribute),也就是说domain是一个属性,type可以关联多个属性,后面用逗号分割,比如:
type traced_probes, domain, coredomain, mlstrustedsubject;
表示traced_probes这个type关联上了domain、coredomain、mlstrustedsubject这三个属性
如果在type定义的时候没有关联属性,后面也可以通过typeattribute关键字来关联
typeattribute type_name attribute_name;
2、attribute的定义规则
attribute attribute_name;
代码里面属性的定义在:
/android/system/sepolicy/public/attributes
# All types used for processes.
attribute domain;
# All types used for files that can exist on a labeled fs.
# Do not use for pseudo file types.
# On change, update CHECK_FC_ASSERT_ATTRS
# definition in tools/checkfc.c.
attribute file_type;
# All types used for domain entry points.
attribute exec_type;
# All types used for /data files.
attribute data_file_type;
expandattribute data_file_type false;
# All types in /data, not in /data/vendor
attribute core_data_file_type;
expandattribute core_data_file_type false;
# All types in /vendor
attribute vendor_file_type;
......
3、type和attribute的区别
关于type和attribute,一开始接触,很难理解这两个的区别
它们两个有很多类似的点,但是又不大一样:
- type和attribute都是不能重复定义的,它们位于同一个命令空间,也就意味着定义一个type之后,就不能定义一个同名的attribute
下面的都会定义会报错提示,重复定义
type system_app, domain;
attribute system_app;
type system_app, domain;
type system_app, coredomain, mlstrustedsubject;
- type就是一个类型;attribute可以找到所有关联了这个属性的type,可以把它当成一个集合、组、标签
attribute其实就是为了方便书写te规则,我们可以用attribute找到所有关联了属性的type集合,而不用每一个都写出来
3.2.3 例子
上面的概念比较抽象,通常我们能比较快理解的是如何在te文件里使用allow语句添加权限,但是对于neverallow语句所表达的意思就很难理解了
下面我用例子来解释(提到的权限只是示例,并不一定是代码里面的,也有可能违反neverallow规则)
1、假如有几个文件,以及它们的安全上下文:
console:/ # ls -Z /data/test.txt
u:object_r:system_data_file:s0 /data/test.txt
console:/ # ls -Z /data/vendor/log_test.txt
u:object_r:vendor_data_file:s0 /data/vendor/log_test.txt
console:/ # ls -Z /data/media/media_test.txt
u:object_r:media_rw_data_file:s0 /data/media/media_test.txt
2、有如下几个脚本,内容都一样
/system/bin/testA.sh
/vendor/bin/testB.sh
/vendor/bin/testC.sh
echo "hello world" > /data/test.txt
echo "hello world" > /data/vendor/log_test.txt
echo "hello world" > /data/media/media_test.txt
3、init.rc里面的定义如下:
service testA /system/bin/testA.sh
user root
group root
disabled
oneshot
seclabel u:r:testA:s0
service testB /vendor/bin/testB.sh
user root
group root
disabled
oneshot
seclabel u:r:testB:s0
service testC /vendor/bin/testC.sh
user root
group root
disabled
oneshot
seclabel u:r:testC:s0
4、假设系统里面定义的type和attribute只有下面这些:
type system_server, coredomain, domain;
type testA, domain;
type testB, domain;
type performanced, domain, coredomain;
type kernel, domain, data_between_core_and_vendor_violators

本文详细探讨了Android SELinux的基础概念、开机初始化、策略编译过程、权限检查机制,以及如何处理neverallow规则,通过实例解析其工作原理和常见问题解决方案。
最低0.47元/天 解锁文章
1543

被折叠的 条评论
为什么被折叠?



