Selinux 相关知识
0. 背景知识
背景知识,我们这里不过多的了解,直接来一些实用的。
1. selinux 的分离
在Android8.0中,SELinux策略分离成平台(platform)和非平台(non-platform)两部分,而平台策略为了给非平台作者导出特定的类型和属性,又分为平台私有(platform private)和平台公有(platform public)部分。
1.1 平台公有策略(platform public seoplicy)
平台共有策略全部定义在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是说,设备制造商的sepolicy作者在non-platform下可以对platform public sepolicy的策略进行扩展。
1.2 平台私有策略(platform private seoplicy)
与公有策略相反,被声明为私有策略的type或attribute对non-platform的策略作者是不可见的,这里有些费解,我们举例来说,这里以8.0版本的aosp源代码中的/system/sepolicy/private/目录下的atrace.te文件为例;
8.0版本的aosp中的/system/sepolicy/private/file_contexts定义了“/system/bin/atrace u:object_r:atrace_exec:s0”
然后在/system/sepolicy/private/atrace.te中定义atrace相关的规则;
我们在device/qcom/sepolicy/common目录下新增一个atrace.te文件,并添加规则 "allow atrace sdcardfs:file read;"
当我们make进行编译时会在校验的时候失败,提示我们“device/qcom/sepolicy/common/atrace.te:2:ERROR 'unknown type atrace' at token ';' on line 23355”,那么也就是说private策略中的type和attribute对我们是不可见的。
2. selinux 客制的几个步骤
这里主要解释一下,现在selinux客制化定制用到步骤和宏
2.1 上下文定义
注意:标准的label取名方式是需要被遵守的,因为很多宏里面就直接用了。
2.1.1 hwservice_contexts
这里标注的是使用hwbinder的服务通信的接口
标准的label取名方式是以_hwservice结尾
hwbinder是框架与供应商内容之间的ipc通信模块
同理,还有个vndbinder,是供应商内容之间的ipc通信模块
Android 8 之后,原先的binder只适用于框架内通信
2.1.2 service_contexts
这里记录的是注册/寻找 binder service 的时候的key
对应到的是
ServiceManager.addService(String name, IBinder service)
publishBinderService(String name, IBinder service)
ServiceManager.getService(String name)
中的name
标准的label取名方式是以_service结尾
2.1.3 file_contexts/genfs_contexts
它们都是用来指定文件的上下文标签
一般来说,file_contexts用来指定那些inode能够保存上下文信息的文件系统的文件上下文
比如system和vendor分区
这些上下文被应用的时机是打包生成镜像的时候
genfs_contexts 则一般用来记录诸如/sys、/proc这样的没有inode的文件系统的上下文信息
genfs_contexts 被应用的时机是在开机时
但是,有一种特殊情况,那就是由于genfs_contexts并不支持正则匹配,因此某些需要正则匹配的 /sys或者/proc内容依然会被放到file_contexts中,这些内容的应用时机也是在开机时
标准的label取名方式:
- 可执行文件 以_exec结尾
- 其它文件,按需 或 按照system/sepolicy中的某些已经type的东西进行定义
2.2 宏定义
2.2.1 hal_attribute(<hal_name>)
用来定义三个attribute,分别是:1 2 3 | hal_<hal_name> hal_<hal_name>_client hal_<hal_name>_server |
但是在device tree中直接使用这个宏会导致大规模的neverallow错误,第三方有个workaround
https://review.lineageos.org/c/LineageOS/android_device_lineage_sepolicy/+/286541
暂时还不明白原理
2.2.2 hal_client_domain(, <hal_type>)
将<domain>定义为<hal_type>_client
2.2.3 hal_server_domain(, <hal_type>)
将<domain>定义为<hal_type>_server
2.2.4 domain_auto_trans(, , )
当<olddomain>执行label为<type>的文件时,自动转换进程的domain为<newdomain>
2.2.5 init_daemon_domain()
这是对上面那个宏的进一步封装
当init进程(domain为init的进程)执行被label为<domain>_exec的文件时,自动转换进程domain为<domain>
这是非常常用且重要的一个宏,在为新的可执行文件配置sepolicy的时候必然会用到
从这里可以看出按照标准进行命名的重要性了吧
2.2.6 binder_use / vndbinder_use / hwbinder_use ()
允许<domain>使用不同种类的binder
如果一个服务需要使用binder进行通信(包括向对应service manager注册服务),则需要进行此声明
注意:对于使用hwbinder的服务,如果已经为其定义了hal_server_domain或hal_client_domain,则无需再声明hwbinder_use,原因是上述两个宏会自动将<domain>标注为halserverdomain,从而间接获得hwbinder的使用权限
2.2.7 binder_call(, )
允许<clientdomain>向<serverdomain>发起binder IPC通信
2.2.8 add_hwservice(, )
允许<domain>向hwservice manager注册<service>接口
<service>接口的具体信息定义在hwservice_contexts中
它会自动生成neverallow规则,不再允许别的服务注册这一接口
2.2.9 hal_attribute_hwservice(, )
这是对上面那个宏的进一步封装
它调用add_hwservice(<attribute>_server, <service>)
并允许<attribute>_client向hwservice manager搜索这个服务
它会自动生成neverallow规则,不再允许非_server或_client的domain注册或查找服务
说白了,允许服务端增加服务接口,允许客户端查找获取服务
很显然,它是需要与hal_attribute、hal_client_domain、hal_server_domain配合使用的
又是一个规范命名的重要性?
2.3 流程
常见的,套路?
2.3.1 一般可执行文件
- 创建两个type。一个作为可执行文件执行时的domain,另一个则是给可执行文件的本体使用(<domain>_exec)
- 在file_contexts中,为可执行文件本体打上<domain>_exec的type
- 使用init_daemon_domain来实现执行可执行文件时自动切换domain(否则所有的scontext都会为init)
- 根据其所需权限,为其撰写规则
2.3.2 HIDL HAL
- HAL本身是可执行文件,因此在可执行文件的基础上进行
- 配置hwservice_contexts,声明HAL的接口
- 额外声明hal_attribute,即hal本体、_server和_client的attribute
- 使用hal_server_domain将上述“一般可执行文件”中的domain定义为server
- 将使用HAL的对象定义为hal_client_domain
- 使用add_hwservice允许server增加服务
- 使用binder_call允许server和client之间进行通信
3 app 和selinux
SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
1.untrusted_app 第三方app,没有Android平台签名,没有system权限
2.platform_app 有android平台签名,没有system权限
3.system_app 有android平台签名和system权限
4.untrusted_app_25 第三方app,没有Android平台签名,没有system权限,其定义如下This file defines the rules for untrusted apps running with targetSdkVersion <= 25.
从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app按照这个进行排序
参考链接
https://blog.xzr.moe/archives/111/
https://www.freesion.com/article/6573116485/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异