Android 的 SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)系统,用于增强 Linux 内核的安全性。它在传统的自主访问控制(DAC)基础上,通过定义精细的策略规则来限制进程和用户的权限,从而减少潜在的安全风险。以下是 Android SELinux 权限设计的详细介绍:
1. SELinux 的基本概念
SELinux 最初由美国国家安全局(NSA)开发,后来被集成到 Linux 内核中。Android 从 4.3 版本开始引入 SELinux,并在 5.0 及以后版本中默认启用强制模式(Enforcing Mode)。
核心思想:
- 标签化(Labeling):所有系统资源(文件、进程、设备等)都被分配一个安全上下文(Security Context)。
- 策略规则(Policy Rules):明确规定了哪些主体(如进程)可以访问哪些客体(如文件),以及允许的操作类型(如读、写、执行)。
2. SELinux 的安全上下文
每个对象的安全上下文格式为:user:role:type:level
(在 Android 中通常简化为 u:object_r:type:s0
)。
- user:用户标识(Android 中通常为
u
)。 - role:角色(Android 中主体为
r
,客体为object_r
)。 - type:最重要的字段,用于定义对象的类型(如进程的
domain
或文件的type
)。 - level:可选的多级安全(MLS)字段(Android 中通常为
s0
)。
示例:
- 进程上下文:
u:r:init:s0
- 文件上下文:
u:object_r:system_file:s0
3. Android 的 SELinux 策略
Android 的 SELinux 策略通过 .te
(Type Enforcement)文件定义,编译后生成二进制策略文件 sepolicy
。策略规则主要包括:
a. 类型强制(Type Enforcement, TE)
- domain:进程的类型(如
init
、zygote
、system_server
)。 - type:文件的类型(如
system_file
、app_data_file
)。 - 规则语法:
示例:允许allow domain type:class permission;
mediaserver
进程访问audio_device
:allow mediaserver audio_device:chr_file { read write };
b. 属性(Attributes)
用于分组类型,简化规则管理。例如:
attribute domain;
attribute coredomain;
然后将类型关联到属性:
type system_server, domain, coredomain;
c. 宏(Macros)
Android 定义了大量宏来简化策略编写,例如:
unix_socket_connect(domain, type, class)
:允许域连接到 Unix 套接字。file_type_auto_trans(domain, dir_type, file_type)
:自动为新创建的文件分配类型。
4. Android 的 SELinux 模式
- Enforcing:强制执行策略,拒绝未经授权的访问。
- Permissive:仅记录违规行为,不拒绝访问(用于调试)。
- Disabled:完全禁用 SELinux。
通过 getenforce
命令可以查看当前模式,通过 setenforce
可临时切换模式(需 root 权限)。
5. Android 的策略文件结构
策略文件位于 /system/etc/selinux
(系统分区)和 /vendor/etc/selinux
(厂商分区):
sepolicy
:二进制策略文件。*.te
:源代码文件(如init.te
、system_server.te
)。file_contexts
:定义文件的安全上下文。property_contexts
:定义系统属性的安全上下文。service_contexts
:定义 Binder 服务的安全上下文。
6. 关键策略设计
a. 进程隔离
- 每个进程运行在独立的域(domain)中,例如:
init
:u:r:init:s0
system_server
:u:r:system_server:s0
- 应用进程:
u:r:appdomain:s0:c512,c768
b. 最小权限原则
- 默认拒绝所有访问,仅允许显式声明的规则。
- 例如,普通应用无法直接访问设备文件或系统配置。
c. Binder IPC 控制
通过 service_contexts
和 binder_call
规则限制进程间通信:
allow domain A, B:binder call;
d. 文件系统标签
通过 file_contexts
定义文件的安全上下文,例如:
/system/bin/init u:object_r:init_exec:s0
/data/adb/modules u:object_r:adb_data_file:s0
7. 调试与审计
- 日志查看:通过
dmesg
或logcat
查看 SELinux 拒绝事件(关键字avc: denied
)。 - audit2allow:将拒绝日志转换为策略规则(需 PC 端工具)。
- 宽容模式调试:临时设置为
permissive
模式以收集完整日志。
示例调试命令:
adb shell su root dmesg | grep avc
8. Android 的 SELinux 分层策略
从 Android 8.0 开始,SELinux 策略分为两层:
- 平台策略:AOSP 提供的通用规则。
- 厂商策略:OEM/SoC 厂商在
/vendor/etc/selinux
中扩展的规则。
通过 neverallow
规则防止策略被恶意放宽:
neverallow { appdomain -bluetooth } bluetooth_device:chr_file { open read write };
9. 挑战与限制
- 兼容性:旧设备或第三方模块可能需要放宽策略。
- 性能:策略规则过多可能影响启动速度。
- 复杂性:策略调试需要深入理解上下文和规则。
10. 示例:为一个新服务添加 SELinux 规则
假设新增一个守护进程 mydaemon
:
- 定义进程域:
type mydaemon, domain; type mydaemon_exec, exec_type, file_type;
- 在
file_contexts
中标记可执行文件:/system/bin/mydaemon u:object_r:mydaemon_exec:s0
- 定义访问规则:
allow mydaemon system_file:file { read execute }; allow mydaemon self:process { sigchld };
总结
Android 的 SELinux 设计通过强制访问控制、最小权限原则和精细的策略规则,显著提升了系统安全性。其核心在于类型强制、安全上下文和分层策略管理,尽管增加了复杂性,但有效遏制了恶意软件的横向移动和权限滥用。开发者需熟悉策略语法和调试工具,才能高效处理相关问题。
结束语
Flutter是一个由Google开发的开源UI工具包,它可以让您在不同平台上创建高质量、美观的应用程序,而无需编写大量平台特定的代码。我将学习和深入研究Flutter的方方面面。从基础知识到高级技巧,从UI设计到性能优化,欢饮关注一起讨论学习,共同进入Flutter的精彩世界!