AndroidP SEAndroid 项目实战

1、介绍

   首先什么是 SEAndroid,我们都知道 Android 是基于 linux系统搭建的,而 SELinux(Security-EnhancedLinux) 是美国国家安全局(NSA)对于强
制访问控制的实现,是 Linux 历史上最杰出的新安全子系统,SEAndroid 也是基于 SELinux 从 Android 4.4平台之后加入到 Android 系统的,
SEAndroid在SELinux的基础上添加了新的访问控制,比如跨进程的binder调用、property的读 写等。

2、如何配置

这篇文章可能不太适合初次接触 SEAndroid 的人,主要是讲解如何在android 平台上配置定制Android系统的 sepolicy。我做的是车机端的开发,所以以下均以基于android 的车机开发为例子。

2.1、sepolicy的来源

   一个完整的android 车机开发,sepolicy的来源主要有四个部分:
      1、 system/sepolicy : 这一部分是android原生的所有进程和资源的访问管控
      2、 device/xxx/sepolicy :这一部分是硬件设备提供厂商点亮屏幕自己增加的权限
      3、 ivi/xxx/sepolicy: 这一部分是也是我们开发主要配置的权限,是在原生android系统进行定制的时候产生的权限。
      4、 third-party/app/sepolicy: 这一部分是车机端集成第三方app时,第三方app访问系统资源产生的权限(一般这一部分是不会专门
  进行配置的,因为原生android系统已经把第三方 app所需要的权限已经配置了,如果集成的第三方app还需要特定权限,需要谨慎配置)

2.2 资源划分

我们可以根据label的关联,把所有资源划分为以下几部分:
system/sepolicy/public/file.te

      1、资源label 需要关联fs_type label的,这一部分资源包括 /proc、/sys 目录下的资源。
      2、资源label 需要关联file_type label的, 这一部分资源包括/data、/vendor 、/system 还有厂商自己添加的分区比如 /update、/map、/log等

system/sepolicy/public/device.te

      3、资源label 需要关联 dev_type label, 这一部分资源包括/dev 目录下的设备节点

system/sepolicy/public/property.te

      4、资源label需要关联 property_type label,这一部分资源包括所有property

system/sepolicy/public/hwservice.te

     5、资源label需要关联hwservice_manager_type label, 这一部分资源包括所有的hidl服务

system/sepolicy/public/service.te

    6、 资源label需要关联service_manager_type label,这一部分资源包括所有的aidl服务

还有一部分是socket,这一部分基本都是关联file_type 但是它的创建和使用还是和普通的文件有区别的。

我之所以把上面的资源进行划分是因为在开发中,我遇到的需要添加的资源和进程需要访问的资源就这些,从普通文件到虚拟文件、device、socket、property、hidl服务、aidl服务。

3、进程创建资源

3.1 对执行文件打label

   我们新加了一个进程,执行文件放在 vendor/bin/newprocess, 那我首先要给这个执行文件打label做法如下:
   在file_contexts里面增加如下
   vendor/bin/newProcess u:object_r:newProcess_exec:s0
   
   在newprocess.te(这个是自己新加的) 里面增加如下
   type newProcess, domain;
   type newProcess_exec, exec_type, vendor_file_type, file_type;
   init_daemon_domain(newProcess)

3.2 新增进程创建普通文件、虚拟文件、device

   1、比如 newProcess进程要在/vendor/etc/目录下创建一个test_file.txt 文件,则需要配置权限
    allow newProcess vendor_configs_file:file create_file_perms
   
   2、比如 newProcess进程要在/vendor/etc/目录下创建一个test_dir 目录,则需要配置权限 
   allow newProcess vendor_configs_file:file create_dir_perms
   
   解释:/vendor/etc/ 的 label 就是 vendor_configs_file,可是在实机中ls -lZ 查看。也可以在file_context里面查看。
   对于新建的目录或者文件,如果我们不重新配置label,则会继承上一级的目录label。
   
   如果需要重新赋label则需要以下操作:
   在file_context里面追加
   /vendor/etc/test_file\.txt     u:object_r:my_test_file:s0
   
   在file.te 里面追加
   type my_test_file, vendor_file_type, file_type;
  
  3、比如 newProcess进程要在/sysfs/class/net目录下创建一个test_file.txt 文件,则需要配置权限
       allow newProcess sysfs_net:file create_file_perms
  
   解释:/sysfs/class/net 的 label 就是 sysfs_net,可是在实机中ls -lZ 查看。也可以在genfs_contexts里面查看。
   对于新建的目录或者文件,如果我们不重新配置label,则会继承上一级的目录label。
   
   如果需要重新赋label则需要以下操作:
   在genfs_contexts里面追加
   genfscon sysfs /class/net                         u:object_r:sysfs_net_test_file:s0
   
   在file.te 里面追加
   type sysfs_net_test_file, fs_type, sysfs_type;

 4、比如 newProcess进程要在/dev/ 目录下创建一个kmsg 设备节点,则需要配置权限
   allow newProcess device:file create_file_perms; 
   allow newProcess self:capability {mknod };
  
  解释:/dev/ 的 label 就是 device,可是在实机中ls -lZ 查看。也可以在file_contexts里面查看。
   一般在 /dev 目录下直接创建设备节点需要比较大的权限,还需要 mknod  能力。所以一般要在/dev 下创建设备节点都是init uevent vold等权限
   比较高的进程

   对于新建的设备节点,如果我们不重新配置label,则会继承上一级的目录label。
   
   如果需要重新赋label则需要以下操作:
   在file_contexts里面追加
  /dev/kmsg		u:object_r:kmsg_device:s0
   
   在device.te 里面追加
   type kmsg_device, dev_type;

3.3 新增hidl aidl 服务

   1、我们这里根据系统原有的一个hidl服务,列举它是怎么配置权限的

   /vendor/bin/hw/android.hardware.automotive.audiocontrol@1.0-service 这也是一个执行文件,是一个hidl的服务

   我们要给他配置label在file_contexts里面追加

   /(vendor|system/vendor)/bin/hw/android\.hardware\.automotive\.audiocontrol@1\.0-service    u:object_r:hal_audiocontrol_default_exec:s0

  解释:/(vendor|system/vendor) 就是/vendor 或者 system/vendor
  

 2、之后和上面3.1 一样对执行文件打一个label, 前面三个权限是任何一个hidl执行文件都要配置的
 
 type hal_audiocontrol_default, domain;
 
 type hal_audiocontrol_default_exec, exec_type, vendor_file_type, file_type;

 init_daemon_domain(hal_audiocontrol_default)

 hal_server_domain(hal_audiocontrol_default, hal_audiocontrol)

3、在hwservice_contexts 里面对这个hidl服务提供出去的接口类打label
android.hardware.automotive.audiocontrol::IAudioControl         u:object_r:hal_audiocontrol_hwservice:s0

这样一个hidl服务基本就可以在SEAndroid打开的情况下跑起来了


4、这里先声明一下,自从android8 treble之后,厂商的aidl不允许再注册到servicemanager中了,需要另外注册到vndservicemanager中去。

这里我们在一个aidl文件里面定义了一个aidl 服务的接口,之后将它的子类new 出来注册到vndservicemanager中去。
比如 vndservicemanager.add("test_srevice", new TestService() );

那现在就有一个服务名为test_service的aidl服务了。
首先要给这个服务打label,如下
在vndservicemanager_contexts里面追加
test_service   u:object_r:test_service_type:s0
 
 在 vndservice.te中追加
 test_service_type vndservice_manager_type;

允许test_service  注册到 vndservice_manager中去
allow test_service_type  test_service_type:vndservice_manager add;

3.4 新增property

1、增加property
这里面厂商自己增加的property也需要根据android8 的treble 以避免和android 原生的property冲突

比如增加一个property ro.product.automotive.socversion
需要在property_contexts里面增加 
 ro.product.automotive.socversion   u:object_r:automotive_sys_prop:s0

然后在property.te里面增加
type automotive_sys_prop, property_type;

3.5 创建 socket

1、创建socket
在newprocess.te 里面增加
file_type_auto_trans(newprocess, socket_device, newprocess_socket)

解释:file_type_auto_trans是一个宏定义在system/sepolicy/public/te_macros 里面
/dev/socket(/.*)?	u:object_r:socket_device:s0  , socket_device 就是 目录 /dev/socket/的label我们创建的socket也就是在这个目录下面

总体的一句话就是newprocess 这个进程在 /dev/socket/ 目录下创建了一个socket 文件label由 socket_device 切换到 newprocess_socket。

3.6 给非root权限赋值capability

1、给进程赋值 capability。
 我们知道SEAndroid SELinux 的出现最终都是要显示root 进程的权限,而root进程除了可以不受DAC控制之外,另一个能力就是它具备30多个特殊的capability,比如我们要创建一个节点就是需要能力mknod,如下配置
 
 在newprocess.te 里面增加
 allow newprocess self:capability mkond;
 
 这里假设的是newprocess不具备root权限

以上大体就是一个进程创建某些资源时权限的配置 和创建资源后资源 label 的配置。大家可以先做一个参考。

4、进程访问资源

这里我们还是按照上面的创建资源的顺序来配置访问权限

4.1、访问普通文件 临时文件

假设一个新的进程oldprocess 他的初步权限已经配置好了,接着要读写/vendor/etc/test_file.txt , 而这个文件的label为 my_test_file,则需要配置权限

allow oldprocess my_test_file:file rw_file_perms

rw_file_perms是一个宏定义在  system/sepolicy/public/global_macros 

4.2 访问设备节点

这里要区别这个设备节点是什么访问方式,可以在实机中使用 ls -l查看,如下,在最前面可以看到c b 等,c即使char型字符设备、b就是block 块设备,那么一下的配置就不一样。
在这里插入图片描述

比如 kmsg_device 是一个字符设备节点的label,则oldprocess 进程要对其读写,应配置为

allow oldprocess  kmsg_device:chr_file rw_file_perms

比如 kmsg_device 是一个块设备节点的label,则oldprocess 进程要对其读写,应配置为

allow oldprocess  kmsg_device:blk_file rw_file_perms

4.3 访问一个hidl服务

比如说要访问android.hardware.automotive.audiocontrol@1.0-service ,它的label为 hal_audiocontrol_default,则需要配置

 allow oldprocess hal_audiocontrol_hwservice:hwservice_manager {find}; //意思为允许oldprocess 在hwservucemanager中查找 label为 hal_audiocontrol_hwservice的接口类
 allow oldprocess  hwservicemanager:binder { call transfer };

  binder_call(oldprocess , hal_audiocontrol_default)  //允许oldprocess binder call android.hardware.automotive.audiocontrol@1.0-service。这个binder_call()也是一个宏在 system/sepolicy/public/te_macros里面。

4.4 访问一个aidl服务

就访问我们自己追加的aidl服务

allow oldprocess test_service_type:vndservice_manager find; //允许oldprocess 在 vndservicemanager中find label为test_service_type的aidl服务

allow oldprocess vndservicemanager:binder { call transfer }; // 允许oldprocess 对 vndservicemanager 进行binder的call transfer 

4.5 读写一个 property

就访问上面创建的property。

  set_prop(oldporcess, automotive_sys_prop) //这是一个宏意思就是 oldporcess进程可以对 label为automotive_sys_prop的property进行set,一般用了set这个宏,里面其实就把get也给了。
  
  get_prop(oldporcess, automotive_sys_prop)  // 这就是单给读的权限。

4.6 上面举例创建了一个本地stream 流 socket,这里创建一个网络tcp socket带访问的。

allow oldporcess self:tcp_socket { create_socket_perms listen accept};
allow oldporcess port:tcp_socket name_bind;
allow oldporcess node:tcp_socket node_bind;

下面是访问上面创建的stream socket

  allow oldprocess newprocess_socket:sock_file   write;
  allow oldprocess  newprocess:unix_stream_socket connectto;

呀,以上进程访问资源的权限基本就这些,到此配置算结束了

5 总结

其实这个配置还是比较繁琐的,内容比较复杂的。如果在实际开发中让每个进程的开发者都自己去配置自己的权限,那就要都要学习一遍 SEAndroid,这个是不可能的,那如何在不让模块担当不需要熟悉SEAndroid,而专门的SEAndroid 配置人员又能知道这些模块需要哪些权限呢?这就需要SEAndroid的担当用一个可视化的表格,让担当将需要访问系统的资源都列出来,这也就是我一开始把资源划分的目的,然后由专门的SEAndroid配置人员,根据具体进程,具体访问和申请的资源来配置,具体的权限。

当然这个可视化的表格和生成权限的脚本我们已经实现了,哈哈。

6 遗憾

遗憾点就是没有能力跟到很深的位置去一探究竟 , selinux这一套MAC是如何将进程访问任何资源都做了控制的,哎!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值