找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1113

积分

0

好友

163

主题
发表于 昨天 22:01 | 查看: 1| 回复: 0

Android系统中,强制访问控制(MAC, Mandatory Access Control)的核心实现机制是SELinux(Security-Enhanced Linux)。它与传统的自主访问控制(DAC, Discretionary Access Control)协同工作,显著提升了系统的安全边界,有效遏制了恶意软件或已遭破坏的进程对系统资源的进一步侵害。

Android SELinux 架构简图

1. 核心概念与原理

1.1 DAC与MAC的区别

理解SELinux的前提是厘清DAC和MAC的根本差异:

  • DAC(Linux传统机制): 基于用户ID(UID)和组ID(GID)。一个进程如果拥有某个文件的所有权或相应权限,即可对其进行操作。root用户拥有至高无上的权限。
  • MAC(SELinux机制): 基于预定义的安全策略(Policy)。系统管理员制定规则,明确规定“谁(主体)”可以对“什么(客体)”执行“何种操作”。即便是root进程,只要策略未明确允许,也无法访问受保护的资源。

1.2 SELinux的核心设计

Android主要采用SELinux的类型强制(Type Enforcement, TE)模型。

  • 主体(Subject): 通常指正在运行的进程。
  • 客体(Object): 被访问的资源,如文件、目录、Socket、Binder接口、系统属性等。
  • 安全上下文(Security Context): 每个主体和客体都被贴上一个唯一的标签。
  • 策略(Policy): 定义了拥有特定标签的主体和客体之间被允许的交互规则。

2. 多维度架构解析

2.1 安全上下文(Labeling)

在Android中,可以通过ls -Zps -Z命令查看安全上下文。其格式通常为:user:role:type:sensitivity

例如进程上下文:u:r:system_server:s0

  1. User (u): SELinux用户。在Android中通常固定为 u
  2. Role (r/object_r): 角色。进程通常是 r,文件资源通常是 object_r
  3. Type (type): 这是核心标识。
    • 对于进程,这被称为域(Domain),如 system_serverzygoteuntrusted_app
    • 对于文件,这被称为类型(Type),如 system_fileapp_data_file
  4. Sensitivity (s0): 安全级别(MCS/MLS),用于多级安全隔离等场景。

2.2 运作流程(LSM Hooks)

SELinux通过Linux内核LSM(Linux Security Modules)框架实现其拦截机制:

  1. 进程发起系统调用(如 open()read()binder_call)。
  2. 首先进行DAC检查(传统的Linux权限检查)。若DAC拒绝,直接返回失败。
  3. 若DAC通过,内核调用LSM Hook进入SELinux模块。
  4. SELinux查询AVC(Access Vector Cache, 访问向量缓存,用于缓存策略决策结果)或安全服务器。
  5. 根据策略库(.te 文件编译而成)判断规则是否匹配:allow domain type : class { permission }
  6. 若策略允许,操作继续;若拒绝,则记录 avc: denied 日志并拦截此次访问。

2.3 核心文件与配置

Android的SELinux策略由一系列源文件编译而成,主要位于 /system/sepolicy/device/<vendor>/<board>/sepolicy 目录:

  • *`.te(Type Enforcement)**: 定义类型、属性、宏以及具体的允许(allow`)规则。
  • file_contexts: 定义文件系统在创建或重置时的默认安全标签。
  • property_contexts: 定义Android系统属性(System Properties)的安全标签。
  • service_contexts: 定义Binder服务的安全上下文
  • mac_permissions.xml: 用于基于应用签名的中间件层控制(作为SELinux的补充)。

3. 多层次实现细节

3.1 域转换(Domain Transition)

这是实现Android进程沙箱隔离的关键机制。

  • 系统启动时,init进程拥有非常广泛的权限(u:r:init:s0)。
  • 当init启动zygote时,发生域转换:从 init 域切换到 zygote 域。
  • 当zygote fork应用进程时,再次根据规则转换到特定的应用域(如 untrusted_app)。

关键规则示例(简化表示):

allow init zygote_exec:file execute;
allow init zygote:process transition;
...

这确保了即使由同一个父进程派生,不同的系统服务和用户应用也能运行在严格隔离的沙箱环境中。

3.2 宏与属性(Macros & Attributes)

为了简化策略的管理与编写,Android策略中大量使用了属性进行归类:

  • domain: 所有进程域的基类属性。
  • appdomain: 所有应用进程的属性。
  • netdomain: 需要网络访问权限的进程属性。

通过 allow appdomain system_file:file read; 这样的单条规则,即可一次性授权所有具有 appdomain 属性的应用读取 system_file 类型文件的权限。

3.3 Project Treble 与 策略分离

从Android 8.0开始,为了支持模块化更新(Project Treble),SELinux策略被拆分为两部分:

  1. 平台策略(Platform Policy): 位于 /system 分区,由Google定义和维护,涵盖Android通用框架。
  2. 厂商策略(Vendor Policy): 位于 /vendor 分区,由SoC厂商或设备制造商定义,涵盖硬件驱动和厂商定制功能。

两者在系统启动时通过CIL(Common Intermediate Language)格式动态合并。这种分离确保了在进行系统OTA更新时,厂商的硬件特有权限不会丢失或产生冲突。

4. Android 各版本的演进与要求

SELinux在Android上的演进是一个从“宽容”到“强制”,从“整体”到“模块化”的持续强化过程。

Android 版本 模式/状态 关键变更与机制
Android 4.3 Permissive (宽容模式) 首次引入SELinux,但默认仅记录违规日志而不拦截,用于策略测试和日志收集。
Android 4.4 Enforcing (部分强制) 对核心系统域(installdnetdvoldzygote)启用强制模式。应用层策略仍较为宽松。
Android 5.0 Full Enforcing (全强制) 里程碑。所有域(包括第三方应用)默认处于强制模式。“未明确允许即为拒绝”原则全面落实。
Android 6.0 Hardening 策略增强,引入了对 ioctl 系统调用的精细化过滤(ioctl filtering),防范驱动层漏洞利用。
Android 7.0 Strict Separation 进一步收紧应用沙箱,严格限制应用对 /sys/proc 等文件系统的访问。
Android 8.0 Treble Split 架构重构。策略正式拆分为systemvendor两部分,引入版本化机制确保兼容性。
Android 9.0 Per-App SELinux 为不同特权等级的应用(priv-app, system-app, untrusted-app)提供更细粒度的默认沙箱策略。
Android 10+ Modularization 伴随Apex模块的引入,允许部分系统组件的SELinux策略随模块独立更新。
Android 11-14 Kernel Restrictions 引入对内核内存访问的更严格限制,移除了应用对大量非必要设备节点的访问权限。

5. 开发中的调试与应对

在进行系统应用或ROM定制开发时,SELinux策略是最常遇到的权限障碍之一。

5.1 常用命令

  • getenforce: 查看当前SELinux模式(Enforcing / Permissive)。
  • setenforce 0: 临时切换为宽容模式(需要root权限,通常仅在userdebug或eng版本中有效)。
  • ls -Z /path/to/file: 查看文件或目录的安全上下文。
  • ps -Z: 查看所有进程的安全上下文。

5.2 解决 avc: denied 问题

当功能因权限被阻时,查看 dmesglogcat 日志,搜索关键字 avc:

日志示例:

avc: denied { read } for pid=1234 comm="myapp" name="settings" dev="sda1" ino=5678 scontext=u:r:system_app:s0 tcontext=u:object_r:vendor_file:s0 tclass=file

解读:

  • Action: read (被拒绝的操作)
  • Subject: u:r:system_app:s0 (发起访问的主体)
  • Object: u:object_r:vendor_file:s0 (被访问的客体)
  • Class: file (客体类别)

编写规则:
在对应的 system_app.te 策略文件中添加允许规则:

allow system_app vendor_file:file read;

注意:在实际生产中,直接允许访问宽泛的 vendor_file 类型可能不安全,应优先考虑定义更精确的类型或使用系统已有的安全接口(Binder, Property等)。

5.3 audit2allow 工具

在Android源码开发环境中,提供了 audit2allow 工具,可以自动将avc: denied日志转换为建议的te规则,便于快速分析和策略编写:

adb shell dmesg | audit2allow -p out/target/product/<device>/root/sepolicy

6. 总结

Android的强制访问控制系统是一个基于SELinux构建的深度防御体系。它不再单纯依赖用户身份,而是依托于一个严格定义、中心控制的策略矩阵。从Android 8.0的Treble计划开始,SELinux策略的模块化与版本化已成为Android系统架构现代化与可持续更新的关键支柱。

对于开发者而言,理解DAC是基础,但熟练掌握MAC(SELinux)的原理、策略编写与调试方法,则是深入Android Framework层和系统安全开发领域必须跨越的关键门槛。




上一篇:PyTorch卷积神经网络实战:连续卷积层输出Shape计算与通道数对齐方法
下一篇:三星SATA SSD停产计划曝光:AI行业需求驱动存储芯片市场重构
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 16:32 , Processed in 0.133592 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表