一些sepolicy的进阶内容,那些比较基础的直接忽略了
主要基于aosp的相关注释和文档,外加一些自己的经验和理解

上下文定义

标准的label取名方式是需要被遵守的,因为很多宏里面就直接用了。。

hwservice_contexts

这里标注的是使用hwbinder的服务通信的接口

标准的label取名方式是以_hwservice结尾

hwbinder是框架与供应商内容之间的ipc通信模块

同理,还有个vndbinder,是供应商内容之间的ipc通信模块

Android 8 之后,原先的binder只适用于框架内通信

service_contexts

这里记录的是注册/寻找 binder service 的时候的key
对应到的是
ServiceManager.addService(String name, IBinder service)
publishBinderService(String name, IBinder service)
ServiceManager.getService(String name)
中的name

标准的label取名方式是以_service结尾

file_contexts / genfs_contexts

它们都是用来指定文件的上下文标签
一般来说,file_contexts用来指定那些inode能够保存上下文信息的文件系统 的 文件上下文
比如systemvendor分区
这些上下文被应用的时机是打包生成镜像的时候

genfs_contexts 则一般用来记录诸如/sys/proc这样的没有inode的文件系统的 上下文信息
genfs_contexts 被应用的时机是在开机时

但是,有一种特殊情况,那就是由于genfs_contexts并不支持正则匹配,因此某些需要正则匹配的 /sys或者/proc内容依然会被放到file_contexts中,这些内容的应用时机也是在开机时

标准的label取名方式:

  • 可执行文件 以_exec结尾
  • 其它文件,按需 或 按照system/sepolicy中的某些已经type的东西进行定义

宏定义

hal_attribute(<hal_name>)

用来定义三个attribute
分别是
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
暂时还不明白原理

hal_client_domain(, <hal_type>)

<domain>定义为<hal_type>_client

hal_server_domain(, <hal_type>)

<domain>定义为<hal_type>_server

domain_auto_trans(, , )

<olddomain>执行label为<type>的文件时,自动转换进程的domain为<newdomain>

init_daemon_domain()

这是对上面那个宏的进一步封装
init进程(domain为init的进程)执行被label为<domain>_exec的文件时,自动转换进程domain为<domain>

这是非常常用且重要的一个宏,在为新的可执行文件配置sepolicy的时候必然会用到

从这里可以看出按照标准进行命名的重要性了吧

binder_use / vndbinder_use / hwbinder_use ()

允许<domain>使用不同种类的binder

如果一个服务需要使用binder进行通信(包括向对应service manager注册服务),则需要进行此声明

注意:对于使用hwbinder的服务,如果已经为其定义了hal_server_domainhal_client_domain,则无需再声明hwbinder_use,原因是上述两个宏会自动将<domain>标注为halserverdomain从而间接获得hwbinder的使用权限

binder_call(, )

允许<clientdomain><serverdomain>发起binder IPC通信

add_hwservice(, )

允许<domain>hwservice manager注册<service>接口
<service>接口的具体信息定义在hwservice_contexts

它会自动生成neverallow规则,不再允许别的服务注册这一接口

hal_attribute_hwservice(, )

这是对上面那个宏的进一步封装
它调用add_hwservice(<attribute>_server, <service>)
并允许<attribute>_clienthwservice manager搜索这个服务
它会自动生成neverallow规则,不再允许非_server_clientdomain注册或查找服务

说白了,允许服务端增加服务接口,允许客户端查找获取服务

很显然,它是需要与hal_attributehal_client_domainhal_server_domain配合使用的

又是一个规范命名的重要性?

流程

常见的,套路?

一般可执行文件

  • 创建两个type。一个作为可执行文件执行时的domain,另一个则是给可执行文件的本体使用(<domain>_exec
  • file_contexts中,为可执行文件本体打上<domain>_exectype
  • 使用init_daemon_domain来实现执行可执行文件时自动切换domain(否则所有的scontext都会为init
  • 根据其所需权限,为其撰写规则

HIDL HAL

  • HAL本身是可执行文件,因此在可执行文件的基础上进行
  • 配置hwservice_contexts,声明HAL的接口
  • 额外声明hal_attribute,即hal本体、_server_clientattribute
  • 使用hal_server_domain将上述“一般可执行文件”中的domain定义为server
  • 将使用HAL的对象定义为hal_client_domain
  • 使用add_hwservice允许server增加服务
  • 使用binder_call允许server和client之间进行通信