Android 8.1 从零开始写 HAL – (5) 添加执行权限

Android 8.1 从零开始写 HAL – (5) 添加执行权限

注意:本文基于 Android 8.1 进行分析
Qidi 2020.07.20 (Markdown & Haroopad)


【前言】

Android 上使用 SELinux 来管理权限。 尽管在上一篇文章《Android 8.1 从零开始写 HAL – (4) 编译与打包》中, demoComponent HAL 已经成功编译且打包到系统镜像中,但到目前为止还没有被赋予访问 Binder 的权限。所以我们至少会看到,在将 demoService 注册为 Binder 服务时,日志中会打印类似下方的提示:

[   10.368517] type=1400 audit(1483292256.112:14): avc: denied { add } ...
  •  

这篇文章就是要说明完善 demoComponent HAL 所需要的 SELinux 权限的方法。


一、编写策略文件

依各公司习惯不同,用于配置产品权限的文件一般放在 /device/<CompanyName>/sepolicy/ 或 /device/<CompanyName>/common/sepolicy/ 目录下(也不排除是其它路径的可能性,但肯定是在 device/ 目录下的某个 sepolicy/ 子目录)[1]。在这个目录下,再为不同的部件分别创建相应的子目录,并在这个子目录中新建 *.te 文件和 *_contexts 文件,以添加必要的权限

还是以我正在使用的平台为例,创建新目录 /device/harman/sepolicy/demoComponent/,并在该目录下新建如下图所示的文件:
selinux_files

说明下各文件的内容和作用:

  • file_contexts:
      首先编写 file_contexts 文件。这个文件名是由 SELinux 框架固定的。我们在 file_contexts 中将 demoService 的可执行文件定义为安全对象。

    # define demoService executable binary as a security object
    /vendor/bin/hw/vendor.harman.demoComponent.demoService@1.0-service   u:object_r:demoService_exec:s0
    
  • hwservice_contexts:
      然后,因为 demoComponent HAL 依赖 hwbinder 进行通信,所以我们还需要编写 hwservice_contexts。这个文件名也是由 SELinux 框架固定的。我们在这个文件中将新增的接口定义为一个安全对象,作用和 file_contexts 类似。(如果使用 vndbinder,则应编写 vndservice_contexts
      从 Android 8.0 开始,SELinux 也一分为二成为了 system 部分和 vendor 部分。其中 vendor 部分又因为不同部件使用的 binder 节点不同,从原先唯一的的 service_contexts 中剥离出了 hwservice_contexts 和 vndservice_contexts 两个文件。当使用 /dev/hwbinder 时手动创建前者并在文件中添加定义,当使用 /dev/vndbinder 时创建后者并同样在文件中添加定义。

    # define HAL interface as a security object
    vendor.harman.hardware.demoComponent.demoService::IDemoServiceDef  u:object_r:vendor_demoService_hwservice:s0
    
  • hwservicemanager.te:
      由于我们使用的是 hwbinder 节点,所以还应该编写 hwservicemanager.te。文件名也是固定的。在这个文件中声明 demoService 需要使用 hwbinder。(如果使用 vndbinder,则应编写 vndservicemanager.te

    # grant demoService permission of using hwbinder
    hwbinder_use(demoService)
    
  • hwservice.te:
      同理,编写 hwservice.te。文件名依然是固定的。在这个文件中为 demoService 定义了专属的 hwservice 类型,在添加 “注册服务” 权限时会用到。(如果使用 vndbinder,则应编写 vndservice.te

    # define demoService as hwservice_manager, so it can be added as a hwservice
    type vendor_demoService_hwservice, hwservice_manager_type;
    
  • demoService.te:
      接着编写 demoService.te 文件。 这个文件通常以需要添加权限的对象为名。在这个文件中,我们为 demoService 定义了一个专属的安全域,赋予可 demoService 的执行文件以需要的文件属性,并且为 demoService 域添加和 Binder 操作相关的必要权限,比如 “注册为服务”、“允许 hwbinder 调用” 等。
      不同的 HAL 进程或本地服务要操作的文件不同,其实现的作用也不同,所以这个文件里的内容差异也很大。依照最小权限规则,根据自己的实际需要添加权限即可。[2]

    # define a security domain for demo service
    type demoService, domain;
    
    # specify demo service attributes
    type demoService_exec, exec_type, file_type, vendor_file_type;
    
    # initialize demo service domain
    init_daemon_domain(demoService)
    
    add_hwservice(demoService, vendor_demoService_hwservice)
    
    binder_call(demoService, vndservicemanager)
    binder_call(demoService, hwservicemanager)
    binder_call(demoService, system_app)
    
    allow demoService vndbinder_device:chr_file rw_file_perms;
    allow demoService hwservicemanager_prop:file r_file_perms;
    
  • system_app.te:
      最后,还要为用户进程添加调用权限。因为在下一篇文章《Android 8.1 从零开始写 HAL – (6) 测试HAL》中我会以 APP 对 demoService 的调用为例说明调用过程,所以这里新建 system_app.te。为 system_app 添加通过 hwservice_manager 查找服务、以及通过 binder 调用 demoService 的权限。

    # APP access priviledges for demoService
    binder_call(system_app, demoService)
    allow system_app vendor_demoService_hwservice:hwservice_manager find;
    

二、应用策略文件

为了使新增的安全规则生效,需要将刚刚创建的目录添加到 Makefile 中,这样一来编译镜像时就可以扫描到了。我们一般把这个改动添加到 /device/<CompanyName>/<PlatformName>/<ProductName>/BoardConfig.mk
  这里我改动的文件是 /device/harman/broxton/XXXX/BoardConfig.mk,修改部分如下:

diff --git a/XXXX/BoardConfig.mk b/XXXX/BoardConfig.mk
index 4979507a7..8e700f22d 100755
--- a/XXXX/BoardConfig.mk
+++ b/XXXX/BoardConfig.mk
@@ -72,6 +72,12 @@ BOARD_SEPOLICY_DIRS += device/harman/sepolicy/vold
 INTEL_AUDIO_HAL=imc
 BOARD_SEPOLICY_DIRS += device/harman/sepolicy/audio
+
+########################################################
+# DemoService
+########################################################
+BOARD_SEPOLICY_DIRS += device/harman/sepolicy/demoComponent
+

【结语】

完全编译后,烧写镜像到设备上。待设备启动后,执行命令 ps -A | grep -i demo ,终于可以看到我们的 demoComponent HAL 进程已经随系统启动成功。
process_running
  如果在系统刚启动时执行命令 logcat | grep -i demo,还可以看到 demoComponent HAL 注册为 Binder 服务的日志打印:
register_process
  下一篇文章将以 APP 调用 demoService 为例说明调用方法。


【参考资料】

[1] 《实现 SELinux》, https://source.android.com/security/selinux/implement
[2] 《政策兼容性》, https://source.android.com/security/selinux/compatibility

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值