自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
SELinux 概念
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
请查看此页中的内容,熟悉 SELinux 概念。
强制访问控制
安全增强型 Linux (SELinux) 是适用于 Linux 操作系统的强制访问控制 (MAC) 系统。作为 MAC 系统,它与 Linux 中用户非常熟悉的自主访问控制 (DAC) 系统不同。在 DAC 系统中,存在所有权的概念,即特定资源的所有者可以控制与该资源关联的访问权限。这种系统通常比较粗放,并且容易出现无意中提权的问题。MAC 系统则会在每次收到访问请求时都先咨询核心机构,再做出决定。
SELinux 已作为 Linux 安全模块 (LSM) 框架的一部分实现,该框架可识别各种内核对象以及对这些对象执行的敏感操作。其中每项操作要执行时,系统都会调用 LSM 钩子函数,以便根据不透明安全对象中存储的关于相应操作的信息来确定是否应允许执行相应操作。SELinux 针对这些钩子以及这些安全对象的管理提供了相应的实现,该实现可结合自己的政策来决定是否允许相应访问。
通过结合使用其他 Android 安全措施,Android 的访问权限控制政策能够大大降低遭到入侵的计算机和账号可能蒙受的损失。Android 的自主访问控制和强制访问控制等工具可为您提供一种结构,确保您的软件仅以最低权限级别运行。这样可降低攻击造成的影响,并降低错误进程重写数据甚至是传输数据的可能性。
在 Android 4.3 及更高版本中,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。例如,软件通常情况下必须以 root 用户账号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果根用户遭到入侵,攻击者便可以利用该用户身份向每个原始块存储设备写入数据。不过,可以使用 SELinux 为这些设备添加标签,以便被分配了 root 权限的进程可以只向相关政策中指定的设备写入数据。这样一来,该进程便无法覆盖特定原始块存储设备之外的数据和系统设置。
如需更多安全威胁示例以及使用 SELinux 解决安全威胁的方法,请参阅用例。
强制执行级别
SELinux 可以在各种模式下实现:
- 宽容模式 - 仅记录但不强制执行 SELinux 安全政策。
- 强制模式 - 强制执行并记录安全政策。如果失败,则显示为 EPERM 错误。
在选择强制执行级别时只能二择其一,您的选择将决定您的政策是采取操作,还是仅允许您收集潜在的失败事件。宽容模式在实现过程中尤其有用。
类型、属性和规则
Android 依靠 SELinux 的类型强制执行 (TE) 组件来实施其政策。这表示所有对象(例如文件、进程或套接字)都具有相关联的类型。例如,默认情况下,应用的类型为 untrusted_app
。对于进程而言,其类型也称为域。可以使用一个或多个属性为类型添加注释。属性可用于同时指代多种类型。
对象会映射到类(例如文件、目录、符号链接、套接字),并且每个类的不同访问权限类型由权限表示。
例如,file
类存在权限 open
。虽然类型和属性作为 Android SELinux 政策的一部分会进行定期更新,但权限和类是静态定义的,并且作为新 Linux 版本的一部分也很少进行更新。
政策规则采用以下格式:allow source target:class permissions;
,其中:
- source - 规则主题的类型(或属性)。谁正在请求访问权限?
- 目标 - 对象的类型(或属性)。对哪些内容提出了访问权限请求?
- 类 - 要访问的对象(例如文件、套接字)的类型。
- 权限 - 要执行的操作(或一组操作,例如读取、写入)。
规则的一个示例如下:
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
字段(请参阅明确性)。上一部分介绍了 type
字段。categories
是 SELinux 中多级安全 (MLS) 支持的一部分。在 Android 12 及更高版本中,类别用于:
- 分隔应用数据,使其不被其他应用访问。
- 分隔不同实际用户的应用数据。
明确性
Android 并不会使用 SELinux 提供的所有功能。阅读外部文档时,请记住以下几点:
- AOSP 中的大部分政策都是使用内核政策语言定义的。在使用通用中间语言 (CIL) 时,会存在一些例外情况。
- 不使用 SELinux 用户。唯一定义的用户是
u
。必要时,系统会使用安全上下文的类别字段表示实际用户。
- 不使用 SELinux 角色和基于角色的访问控制 (RBAC)。定义并使用了两个默认角色:
r
(适用于主题)和 object_r
(适用于对象)。
- 不使用 SELinux 敏感度。已始终设置好默认的
s0
敏感度。
- 不使用 SELinux 布尔值。为设备构建政策后,政策将不依赖于设备状态。这简化了政策的审核和调试过程。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# SELinux concepts\n\nReview this page to become familiar with SELinux concepts.\n\nMandatory access control\n------------------------\n\nSecurity Enhanced Linux (SELinux), is a mandatory access control (MAC) system\nfor the Linux operating system. As a MAC system, it differs from Linux's\nfamiliar discretionary access control (DAC) system. In a DAC system, a concept\nof ownership exists, whereby an owner of a particular resource controls access\npermissions associated with it. This is generally coarse-grained and subject\nto unintended privilege escalation. A MAC system, however, consults a central\nauthority for a decision on all access attempts.\n\nSELinux has been implemented as part of the Linux Security Module (LSM)\nframework, which recognizes various kernel objects, and sensitive actions\nperformed on them. At the point at which each of these actions would be\nperformed, an LSM hook function is called to determine whether or not the\naction should be allowed based on the information for it stored in an opaque\nsecurity object. SELinux provides an implementation for these hooks and\nmanagement of these security objects, which combine with its own policy, to\ndetermine the access decisions.\n\nAlong with other Android security measures, Android's access control\npolicy greatly limits the potential damage of compromised machines and\naccounts. Using tools like Android's discretionary and mandatory access\ncontrols gives you a structure to ensure your software runs only at the minimum\nprivilege level. This mitigates the effects of attacks and reduces the\nlikelihood of errant processes overwriting or even transmitting data.\n\nIn Android 4.3 and higher, SELinux provides a mandatory access control (MAC)\numbrella over traditional discretionary access control (DAC) environments. For\ninstance, software must typically run as the root user account to write to raw\nblock devices. In a traditional DAC-based Linux environment, if the root user\nbecomes compromised that user can write to every raw block device. However,\nSELinux can be used to label these devices so the process assigned the root\nprivilege can write to only those specified in the associated policy. In this\nway, the process cannot overwrite data and system settings outside of the\nspecific raw block device.\n\nSee [Use Cases](/docs/security/features/selinux/implement#use_cases)\nfor more examples of threats and ways to address them with SELinux.\n\nEnforcement levels\n------------------\n\nSELinux can be implemented in varying modes:\n\n- *Permissive* - SELinux security policy isn't enforced, only logged.\n- *Enforcing* - Security policy is enforced and logged. Failures appear as EPERM errors.\n\nThis choice is binary and determines whether your policy takes action or merely\nallows you to gather potential failures. Permissive is especially useful during\nimplementation.\n\nTypes, attributes, and rules\n----------------------------\n\nAndroid relies on the Type Enforcement (TE) component of SELinux for its\npolicy. It means that all objects (such as, file, process or socket) have a\n*type* associated with them. For instance, by default, an app\nhas the type `untrusted_app`. For a process, its type is also\nknown as its *domain* . It's possible to annotate a type with one or\nmany *attributes*. Attributes are useful to refer to multiple types\nat the same time.\n\nObjects are mapped to [**classes**](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/private/security_classes)\n(for example, a file, a directory, a symbolic link, a socket) and the different kinds of access\nfor each class are represented by [**permissions**](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/private/access_vectors).\nFor instance, the permission `open` exists for the class\n`file`. While types and attributes are regularly updated as part of\nthe Android SELinux policy, permissions and classes are statically defined and\nrarely updated as part of a new Linux release.\n\nA policy *rule* comes in the form:\n`allow `*source*` `*target* `:`*class*` `*permissions*`;`\nwhere:\n\n- *Source* - The type (or attribute) of the subject of the rule. *Who is requesting\n the access?*\n- *Target* - The type (or attribute) of the object. *To what is the access\n requested?*\n- *Class* - The kind of object (for example, file, socket) being accessed.\n- *Permissions* - The operation (or set of operations) (efor example, read, write) being performed.\n\nAn example of a rule is: \n\n```\nallow untrusted_app app_data_file:file { read write };\n```\n\nThis says that apps are allowed to read and write files labeled\n`app_data_file`. There exist other types for apps. For\ninstances, `isolated_app` is used for app services with\n`isolatedProcess=true` in their manifest. Instead of repeating the\nrule for both types, Android uses an attribute named `appdomain`\nfor all the types that covers apps: \n\n```\n# Associate the attribute appdomain with the type untrusted_app.\ntypeattribute untrusted_app appdomain;\n\n# Associate the attribute appdomain with the type isolated_app.\ntypeattribute isolated_app appdomain;\n\nallow appdomain app_data_file:file { read write };\n```\n\nWhen a rule is written that specifies an attribute name, that name is\nautomatically expanded to the list of domains or types associated with the\nattribute. Some notable attributes are:\n\n- `domain` - attribute associated with all process types,\n- `file_type` - attribute associated with all file types.\n\n### Macros\n\nFor file access in particular, there are many kinds of permission to\nconsider. For instance, the `read` permission isn't enough to open the\nfile or call `stat` on it. To simplify the rule definition, Android\nprovides a set of macros to handle the most common cases. For example, in order\nto include the missing permissions such as `open`, the rule above\ncould be rewritten as: \n\n```\nallow appdomain app_data_file:file rw_file_perms;\n```\n\nSee the [`global_macros`](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/public/global_macros)\nand [`te_macros`](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/public/te_macros)\nfiles for more example of useful macros. Macros should be used whenever possible\nto help reduce the likelihood of failures due to denials on related\npermissions.\n\nOnce a type is defined, it needs to be associated with the file or process\nit represents. See [Implementing SELinux](/docs/security/features/selinux/implement#context-files)\nfor more details on how this association is done. For further information on\nrules, see the\n[SELinux Notebook](https://github.com/SELinuxProject/selinux-notebook/blob/main/src/avc_rules.md).\n\nSecurity context and categories\n-------------------------------\n\nWhen debugging SELinux policies or labelling files (using\n`file_contexts` or when ing `ls -Z`), you might come\nacross a *security context* (also known as a *label* ). For\nexample:\n`u:r:untrusted_app:s0:c15,c256,c513,c768`. A security context has the format:\n`user:role:type:sensitivity[:categories]`. You can usually ignore the\n`user`, `role` and `sensitivity` fields of a\ncontext (see [Specificity](#specificity)). The `type`\nfield is explained in the previous section. `categories` are part of\nthe [Multi-Level Security (MLS)](https://github.com/SELinuxProject/selinux-notebook/blob/main/src/mls_mcs.md#multi-level-and-multi-category-security)\nsupport in SELinux. In Android 12 and higher, categories are used to:\n\n- Isolate the app data from access by another app,\n- Isolate the app data from one physical user to another.\n\n\u003cbr /\u003e\n\nSpecificity\n-----------\n\nAndroid doesn't use all the features provided by SELinux. When reading\nexternal documentation, keep these points in mind:\n\n- The majority of the policies in AOSP are defined using the Kernel Policy Language. There are some exceptions for using Common Intermediate Language (CIL).\n- SELinux *users* aren't used. The only user defined is [`u`](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/private/users). When necessary, physical users are represented using the categories field of a security context.\n- SELinux *roles* and Role-Based Access Control (RBAC) aren't used. Two default roles are defined and used: [`r`](https://android.googlesource.com/platform/system/sepolicy/+/refs/heads/android16-release/private/roles_decl) for subjects and `object_r` for objects.\n- SELinux *sensitivities* aren't used. The default `s0` sensitivity is always set.\n- SELinux booleans aren't used. When the policy is built for a device, it doesn't depend on the state of the device. This simplifies the auditing and debugging of policies."]]