SELinux 概念

查看此页面以熟悉 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_macroste_macros 文件,了解更多有用的宏示例。应尽可能使用宏,以帮助减少因相关权限被拒绝而导致失败的可能性。

定义类型后,需要将其与它所代表的文件或进程关联。请参阅 实施 SELinux,了解有关如何进行此关联的更多详细信息。有关规则的更多信息,请参阅 SELinux Notebook

安全上下文和类别

在调试 SELinux 策略或标记文件(使用 file_contexts 或使用 ls -Z 时),您可能会遇到 安全上下文(也称为 标签)。例如:u:r:untrusted_app:s0:c15,c256,c513,c768。安全上下文的格式为:user:role:type:sensitivity[:categories]。您通常可以忽略上下文的 userrolesensitivity 字段(请参阅 特殊性)。类型 字段在上一节中已说明。categories 是 SELinux 中 多级安全 (MLS) 支持的一部分。在 Android 12 及更高版本中,categories 用于

  • 隔离应用数据,防止被另一个应用访问,
  • 将应用数据从一个物理用户隔离到另一个物理用户。

特殊性

Android 没有使用 SELinux 提供的所有功能。在阅读外部文档时,请记住以下几点

  • AOSP 中的大多数策略都是使用内核策略语言定义的。使用通用中间语言 (CIL) 有一些例外。
  • 未使用 SELinux 用户。唯一定义的用户是 u。必要时,物理用户使用安全上下文的 categories 字段表示。
  • 未使用 SELinux 角色和基于角色的访问控制 (RBAC)。定义并使用了两个默认角色:r 用于主体,object_r 用于对象。
  • 未使用 SELinux 敏感度。始终设置默认的 s0 敏感度。
  • 未使用 SELinux 布尔值。当为设备构建策略时,它不依赖于设备的状态。这简化了策略的审计和调试。