查看此页面以熟悉 SELinux 概念。
强制访问控制
安全增强型 Linux (SELinux) 是 Linux 操作系统的强制访问控制 (MAC) 系统。作为 MAC 系统,它与 Linux 熟悉的自主访问控制 (DAC) 系统不同。在 DAC 系统中,存在所有权的概念,特定资源的所有者控制与其关联的访问权限。这通常是粗粒度的,并且容易发生意外的特权提升。然而,MAC 系统会咨询中央机构,以决定所有访问尝试。
SELinux 已作为 Linux 安全模块 (LSM) 框架的一部分实现,该框架识别各种内核对象以及对其执行的敏感操作。在执行每个操作时,都会调用 LSM 钩子函数,以根据存储在不透明安全对象中的信息来确定是否应允许该操作。SELinux 为这些钩子和这些安全对象的管理提供了实现,它们与 SELinux 自身的策略相结合,以确定访问决策。
与其他 Android 安全措施一起,Android 的访问控制策略大大限制了受损机器和帐户的潜在损害。使用诸如 Android 的自主和强制访问控制之类的工具,您可以构建一个结构,以确保您的软件仅在最低特权级别运行。这减轻了攻击的影响,并降低了错误进程覆盖甚至传输数据的可能性。
在 Android 4.3 及更高版本中,SELinux 在传统的自主访问控制 (DAC) 环境之上提供了强制访问控制 (MAC) 保护伞。例如,软件通常必须以 root 用户帐户身份运行才能写入原始块设备。在传统的基于 DAC 的 Linux 环境中,如果 root 用户遭到入侵,该用户可以写入每个原始块设备。但是,SELinux 可以用于标记这些设备,以便分配了 root 特权的进程只能写入相关策略中指定的设备。这样,进程就无法覆盖特定原始块设备之外的数据和系统设置。
请参阅 用例,了解有关威胁以及如何使用 SELinux 解决这些威胁的更多示例。
强制级别
SELinux 可以以不同的模式实现
- 宽容模式 - SELinux 安全策略不强制执行,仅记录。
- 强制模式 - 安全策略强制执行并记录。失败会显示为 EPERM 错误。
此选择是二元的,它决定您的策略是采取措施还是仅仅允许您收集潜在的失败。宽容模式在实施期间尤其有用。
类型、属性和规则
Android 依赖 SELinux 的类型强制 (TE) 组件来实现其策略。这意味着所有对象(例如,文件、进程或套接字)都具有与其关联的类型。例如,默认情况下,应用具有 untrusted_app
类型。对于进程,其类型也称为其域。可以为一个类型注释一个或多个属性。属性对于同时引用多个类型很有用。
对象映射到 类(例如,文件、目录、符号链接、套接字),并且每个类的不同类型的访问权限由 权限表示。例如,open
权限存在于 file
类中。虽然类型和属性会定期更新作为 Android SELinux 策略的一部分,但权限和类是静态定义的,并且很少作为新的 Linux 版本的一部分进行更新。
策略规则的形式为:allow source target:class permissions;
其中
- Source - 规则主体的类型(或属性)。 谁在请求访问?
- Target - 对象的类型(或属性)。 请求访问什么?
- Class - 要访问的对象类型(例如,文件、套接字)。
- Permissions - 正在执行的操作(或一组操作)(例如,读取、写入)。
一个规则的示例是
allow untrusted_app app_data_file:file { read write };
这表示允许应用读取和写入标记为 app_data_file
的文件。应用还存在其他类型。例如,isolated_app
用于清单中 isolatedProcess=true
的应用服务。Android 没有为这两种类型重复规则,而是对涵盖应用的所有类型使用名为 appdomain
的属性
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app appdomain; allow appdomain app_data_file:file { read write };
当编写指定属性名称的规则时,该名称会自动扩展为与该属性关联的域或类型列表。一些值得注意的属性是
domain
- 与所有进程类型关联的属性,file_type
- 与所有文件类型关联的属性。
宏
特别是对于文件访问,有很多种权限需要考虑。例如,read
权限不足以打开文件或在其上调用 stat
。为了简化规则定义,Android 提供了一组宏来处理最常见的情况。例如,为了包含诸如 open
之类的缺失权限,上面的规则可以重写为
allow appdomain app_data_file:file rw_file_perms;
请参阅 global_macros
和 te_macros
文件,了解更多有用的宏示例。应尽可能使用宏,以帮助减少因相关权限被拒绝而导致失败的可能性。
定义类型后,需要将其与它所代表的文件或进程关联。请参阅 实施 SELinux,了解有关如何进行此关联的更多详细信息。有关规则的更多信息,请参阅 SELinux Notebook。
安全上下文和类别
在调试 SELinux 策略或标记文件(使用 file_contexts
或使用 ls -Z
时),您可能会遇到 安全上下文(也称为 标签)。例如:u:r:untrusted_app:s0:c15,c256,c513,c768
。安全上下文的格式为:user:role:type:sensitivity[:categories]
。您通常可以忽略上下文的 user
、role
和 sensitivity
字段(请参阅 特殊性)。类型 字段在上一节中已说明。categories
是 SELinux 中 多级安全 (MLS) 支持的一部分。在 Android 12 及更高版本中,categories 用于
- 隔离应用数据,防止被另一个应用访问,
- 将应用数据从一个物理用户隔离到另一个物理用户。
特殊性
Android 没有使用 SELinux 提供的所有功能。在阅读外部文档时,请记住以下几点