深入Android SELinux:从platform_app到system_app,你的应用该选哪个Domain?
2026/5/11 23:36:52 网站建设 项目流程

深入Android SELinux:从platform_app到system_app,你的应用该选哪个Domain?

在Android系统开发中,SELinux(Security-Enhanced Linux)作为强制访问控制(MAC)机制,为系统安全筑起了一道坚实的防线。不同于传统的自主访问控制(DAC),SELinux通过精细的域-类型(domain-type)模型,严格限制进程和资源的交互方式。对于需要深度定制Android系统或开发系统级应用的工程师而言,理解untrusted_appplatform_appsystem_app这三个关键Domain的区别及适用场景,是避免权限问题与安全风险的基础。

1. SELinux Domain的核心分类与权限层级

Android中的SELinux策略将应用划分为三类主要Domain,其权限层级和适用场景截然不同:

1.1 untrusted_app:第三方应用的默认安全沙箱

  • 定义:所有未通过平台签名(platform签名)的第三方应用,默认归类为untrusted_app
  • 权限特点
    • 无法访问系统级资源(如/system分区下的文件)
    • 受限的Binder调用权限
    • 禁止直接操作硬件设备节点
  • 典型场景
    # 查看untrusted_app的SELinux上下文示例 adb shell ps -Z | grep untrusted_app u:r:untrusted_app:s0 u0_a27 2504 1172 com.example.thirdparty

1.2 platform_app:具备平台特权的中间层

  • 定义:通过Android平台签名(LOCAL_CERTIFICATE := platform),但未分配systemUID的应用。
  • 权限特点
    • 可访问部分平台级API(如@hide接口)
    • 允许与系统服务进行受限的Binder通信
    • 仍受限于敏感资源访问(如/data/system目录)
  • 配置示例
    <!-- mac_permissions.xml 定义平台签名 --> <signer signature="@PLATFORM"> <seinfo value="platform" /> </signer>

1.3 system_app:系统级应用的高权限Domain

  • 定义:同时满足平台签名和systemUID分配的应用(如预装系统应用)。
  • 权限特点
    • 允许访问受保护的系统资源(如/data/misc
    • 可调用特权系统API(如DevicePolicyManager
    • 需谨慎控制权限以避免安全漏洞
  • UID关联
    # system_app通常与system用户关联 u:r:system_app:s0 system 2414 1172 com.android.settings

1.4 三域权限对比表

特性untrusted_appplatform_appsystem_app
签名要求platform签名platform签名
UID范围u0_aXu0_aXsystem
数据目录访问仅自身app_data_file受限共享目录全系统目录
Binder调用权限基础API扩展平台API特权系统API
典型应用用户安装的第三方应用系统功能扩展应用核心系统应用

2. Domain分配的关键决策因素

2.1 签名机制与seinfo关联

Domain分配的核心依据是应用的签名和UID,其逻辑关系如下:

  1. 签名检测
    • Platform签名 →seinfo=platform
    • 其他签名 →seinfo=default
  2. UID匹配
    • user=systemdomain=system_app
    • user=_app+seinfo=platformdomain=platform_app
    • user=_app+seinfo=defaultdomain=untrusted_app
# 查看seapp_contexts的匹配规则(Android 12示例) cat /system/etc/selinux/seapp_contexts | grep -E "platform_app|system_app" user=_app seinfo=platform domain=platform_app user=system seinfo=platform domain=system_app

2.2 实际项目中的选择策略

  • 选择platform_app的场景

    • 需要调用@hideAPI但无需系统级权限
    • 作为系统功能扩展模块(如自定义设置项)
    • 示例:实现跨应用数据共享的中间件
      # Android.mk 配置平台签名 LOCAL_CERTIFICATE := platform
  • 选择system_app的场景

    • 需要修改系统配置(如网络策略管理)
    • 直接访问硬件抽象层(HAL)
    • 示例:定制设备管理应用
      <!-- AndroidManifest.xml 声明系统权限 --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" coreApp="true" android:sharedUserId="android.uid.system">

警告:将应用提升为system_app会显著扩大攻击面,必须进行严格的安全审计。

3. 高级配置与策略定制

3.1 自定义Domain的实践方法

对于需要特殊权限组合的应用,可创建自定义Domain:

  1. 定义新类型

    # my_domain.te type my_app, domain; type my_app_exec, exec_type, file_type;
  2. 关联文件上下文

    # file_contexts /system/bin/my_app u:object_r:my_app_exec:s0
  3. 配置seapp_contexts

    # 匹配特定seinfo值 user=_app seinfo=my_custom domain=my_app

3.2 权限边界控制技巧

  • 最小权限原则

    # 仅允许特定目录访问 allow platform_app my_data_file:dir { read write }; allow platform_app my_data_file:file { create open };
  • Binder调用限制

    # 限制跨Domain的Binder通信 neverallow untrusted_app system_server:binder *;

3.3 调试与问题排查

  • AVC日志分析

    adb shell dmesg | grep avc avc: denied { read } for pid=xxx comm="my_app" path="/data/system" dev="dm-0" ino=1234
  • 权限临时调试

    # 切换为Permissive模式(仅调试环境) adb shell setenforce 0

4. 典型场景实战解析

4.1 预装应用的Domain选择

场景:为OEM厂商定制系统级功能模块

  • 方案设计

    • 签名:使用厂商私钥+平台签名
    • UID:共享android.uid.system
    • 策略配置:
      # 允许访问OEM分区 allow system_app oem_data_file:dir rw_dir_perms;
  • 避坑指南

    • 避免直接使用system_app,优先尝试platform_app
    • 必要时创建厂商专属Domain(如vendor_app

4.2 跨进程通信的权限控制

场景:系统服务向platform_app开放API

  1. 服务端声明

    // 添加SELinux权限检查 if (!Binder.getCallingUid() == Process.SYSTEM_UID) { enforceCallingPermission("android.permission.MY_PRIVILEGED"); }
  2. 客户端策略

    # 允许platform_app调用特定Binder接口 allow platform_app system_service:service_manager find;

4.3 数据共享的安全实现

方案对比

方法SELinux配置要点适用Domain
ContentProvider定义独立的content_typeplatform_app
共享UID需统一签名和seinfosystem_app
文件系统权限精确控制目录的type属性自定义Domain
# 共享目录的典型配置 type shared_data_file, file_type, data_file_type; allow { platform_app untrusted_app } shared_data_file:file { read getattr };

在完成多个系统定制项目后,我发现最常见的错误是过度提升应用权限等级。实际上,80%的功能需求通过platform_app配合精细的SELinux策略即可实现,无需冒险使用system_app。当遇到权限问题时,建议优先通过avc_log分析缺失的权限项,而非简单切换Domain。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询