如何分析Android SELinux权限问题

583 阅读6分钟

如何分析Android SELinux权限问题

1 基础知识

1.1 什么是 SELinux?

SELinux 全称安全增强型 Linux(Security-Enhanced Linux)是适用于 Linux 操作系统的强制访问控制系统(MAC,Mandatory Access Control)。

1.2 基本概念

1.2.1 模式

在 Android SELinux 中,有两种强制执行模式,分别是宽容模式和强制模式。

宽容模式: 仅记录但不强制执行 SELinux 安全策略。

强制模式: 强制执行并记录安全政策;如果失败,则报告为 EPERM 错误(Operation not permitted)。

1.2.2 对象

指在 SELinux 中被控制和管理的各种系统资源,例如文件、进程、套接字等。

1.2.3 类型/域

所有的对象都有相关联的类型(type),类型定义了对象的安全属性和上下文,它们描述了对象的特征行为和访问权限。对于进程而言,其类型也称为域(domain)。

1.2.4 属性

可以用一个或多个属性为类型添加注解,不同的类型可以添加相同的属性;反过来属性可以同时指代多种类型。

常用的一些属性:

  • domain:与所有进程类型相关联的属性。
  • appdomain:与所有应用类型相关联的属性。
  • file_type:与所有文件类型相关联的属性。

1.2.5 类

对象会映射到类,例如文件、目录、符号链接、套接字等。

类只标识 SELinux 策略中的主体,描述主体的特征和行为,但并不直接定义其访问权限。

1.2.6 权限

描述对象的可用权限,例如 file 类存在权限 open。

宏: Android SELinux 提供了一系列宏方便定义权限,特别是对于文件权限,read 权限不足以打开相应的文件或对其调用 stat,还需要其他的很多权限,因此 Android 提供了宏来处理最常见的情况。

参考:

1.2.7 规则

指定安全策略的基本单位,用于控制主体对对象的访问权限。

格式:allow source target:class permissions;

  • source:主体的类型或属性,表示谁正在请求权限。
  • target:具体的对象,可以用对象的类型或属性代指,表示对谁提出的请求权限。
  • calss:要访问的对象的类型。
  • permissions:请求了哪些权限。

当编写规则制定了某个属性名称时,该名称会自动扩展为列出与该属性关联的所有类型/域。

例子:

  1. 给应用读取和写入具有 app_data_file 属性的文件:

    allow untrusted_app app_data_file:file { read write };
    
  2. 允许所有具有 appdomain 属性的主体读写具有 app_data_file 属性的文件:

    allow appdomain app_data_file:file { read write };
    

1.2.8 安全上下文

用于标识和控制系统资源访问权限的重要概念,由一系列的安全标签组成。

通过*_contexts或运行 ls -Z查看,进程可以查看 ps -AZ

1.2.9 类别

类别(Category)是一种安全属性,用于进一步细分对象的安全性。

1.3 关键文件

  1. AOSP 政策文件目录:system/sepolicy,通常情况下不直接修改这个目录下的文件。

  2. 设备专用政策文件目录:device/<manufacturer>/<device-name>/sepolicy,可以添加和修改自己的设备专用政策文件。

  3. 政策文件:以 *.te结尾的文件,用于定义域及其标签。

  4. 上下文描述文件:*_contexts

    1. file_contexts:用于为文件分配标签,并提供多种用户空间组件使用;
    2. genfs_contexts:用于为不支持扩展属性的文件系统分配标签,例如 procvfat
    3. property_contexts:用于为 Android 系统属性分配标签;
    4. service_contexts:用于为 Android Binder 服务分配标签;
    5. seapp_contexts:用于为应用进程和 /data/data 目录分配标签;
    6. mac_permissions.xml:用于根据应用签名和应用软件包名称(后者可选)为应用分配 seinfo 标记,seinfo 标记可在 seapp_contexts 文件中用作密钥,以便为带有该 seinfo 标记的所有应用分配标签。
  5. 编译配置文件:BoardConfig.mk,添加或修改政策文件和上下文描述文件后,更新 Makefile 以引用 sepolicy 子目录,Android 开发者提供了系列宏 BOARD_SEPOLICY方便开发,参考:

    • system/sepolicy/README.md
    • system/sepolicy/build/soong/build_files.go
    • system/sepolicy/Android.mk

2 调试

2.1 拒绝事件日志

获取方式:

  1. dmesg | grep avc:
  2. logcat | grep avc:
  3. cat /sys/fs/pstore/console-ramoops:获取上次启动时的拒绝事件日志。

例子:

SELinux : avc:  denied  { add } for pid=7590 uid=1000 name=vendor.platformservice scontext=u:r:system_app:s0 tcontext=u:object_r:platformservice_service:s0 tclass=service_manager permissive=0

分析:

  1. scontext=u:r:system_app:s0:谁缺少了权限?system_app
  2. denied { add }:缺少了什么权限?add
  3. tcontext=u:object_r:platformservice_service:s0:对谁缺少了权限?platformservice_service
  4. tclass=service_manager:它是什么类型?service_manager

连贯起来,就是:

system_appservice_manager类型的 platformservice_service缺少了 add权限。

解决方法:

  • 修改 system_app.te,增加 add 权限;
  • allow system_app platformservice_service:service_manager add;

2.2 查看 seinfo

  • 查看文件相关的 seinfo:file_contextsls -Z
  • 查看进程或应用的 seinfo:ps -AZ

2.3 编译调试

# 编译
mmm system/sepolicy

# 替换更新
adb push /xxx/system/etc/selinux /system/etc/
adb push /xxx/vendor/etc/selinux /vendor/etc/
adb push /xxx/system/system_ext/etc/selinux /system_ext/etc/
adb push /xxx/system/product/etc/selinux /product/etc/
adb reboot

3 常见例子

3.1 新增 Native 服务

  1. service.te新增服务类型type service, service_manager_type
  2. 在服务安全上下文service_contexts中添加安全标签:service u:object_r:service_service:s0

3.2 新增 Java 服务

  1. service.te新增服务类型type xxxApp, service_manager_type
  2. 在服务安全上下文service_contexts中添加安全标签:xxxApp u:object_r:xxxApp_service:s0

3.3 新增可执行文件

以新增 MAC 读写工具operate_mac为例:

  1. 新增operate_mac.te以添加operate_mac的类型:

    type operate_mac, domain;
    type operate_mac_exec, exec_type, file_type;
    init_daemon_domain(operate_mac);
    
  2. 在文件安全上下文 file_contexts中添加安全标签:/system/bin/operate_mac u:object_r:operate_mac_exec:s0

3.4 新增设备节点

以新增/dev/tpinfo节点为例:

  1. device.te新增节点类型type vendor_tpinfo_device, dev_type;
  2. 在文件安全上下文file_contexts中添加安全标签/dev/tpinfo u:object_r:vendor_tpinfo_device:s0

3.5 新增属性

以新增vendor.overlay.dtbo属性为例:

  1. property.te新增属性类型type vendor_overlay_dtbo_prop, property.type;
  2. 在属性安全上下文property_contexts中添加安全标签:vendor.overlay.dtbo u:object_r:vendor_overlay_dtbo_prop:s0

参考文档

  1. Android 中的安全增强型 Linux | Android 开源项目 | Android Open Source Project (google.cn)
  2. SEforAndroid - SELinux Wiki (selinuxproject.org)
  3. Android SELinux权限概念和配置说明-腾讯云开发者社区-腾讯云 (tencent.com)
  4. selinux-notebook/src/seandroid.md at main · SELinuxProject/selinux-notebook · GitHub
  5. SELinux - boardmix