page.title=SELinux concepts @jd:body

In this document

Review this page to become familar with the concepts at play within SELinux.

Mandatory access control

Security Enhanced Linux (SELinux), is a mandatory access control (MAC) system for the Linux operating system. As a MAC system, it differs from Linux’s familiar discretionary access control (DAC) system. In a DAC system, a concept of ownership exists, whereby an owner of a particular resource controls access permissions associated with it. This is generally coarse-grained and subject to unintended privilege escalation. A MAC system, however, consults a central authority for a decision on all access attempts.

SELinux has been implemented as part of the Linux Security Module (LSM) framework, which recognizes various kernel objects, and sensitive actions performed on them. At the point at which each of these actions would be performed, an LSM hook function is called to determine whether or not the action should be allowed based on the information for it stored in an opaque security object. SELinux provides an implementation for these hooks and management of these security objects, which combine with its own policy, to determine the access decisions.

In conjunction with other Android security measures, Android's access control policy greatly limits the potential damage of compromised machines and accounts. Using tools like Android's discretionary and mandatory access controls gives you a structure to ensure your software runs only at the minimum privilege level. This mitigates the effects of attacks and reduces the likelihood of errant processes overwriting or even transmitting data.

Starting in Android 4.3, SELinux provides a mandatory access control (MAC) umbrella over traditional discretionary access control (DAC) environments. For instance, software must typically run as the root user account to write to raw block devices. In a traditional DAC-based Linux environment, if the root user becomes compromised that user can write to every raw block device. However, SELinux can be used to label these devices so the process assigned the root privilege can write to only those specified in the associated policy. In this way, the process cannot overwrite data and system settings outside of the specific raw block device.

See Use Cases for more examples of threats and ways to address them with SELinux.

Enforcement levels

Become familiar with the following terms to understand how SELinux can be implemented to varying strengths.

This choice is binary and determines whether your policy takes action or merely allows you to gather potential failures. Permissive is especially useful during implementation.

Unconfined policies are available to help implement SELinux in Android quickly. They are suitable for most root-level applications. But they should be converted to confined policies wherever possible over time to restrict each application to precisely the resources it needs.

Ideally, your policy is both in enforcing mode and confined. Unconfined policies in enforcement mode can mask potential violations that would have been logged in permissive mode with a confined policy. Therefore, we strongly recommend partners implement true confined policies.

Labels, rules and domains

SELinux depends upon labels to match actions and policies. Labels determine what is allowed. Sockets, files, and processes all have labels in SELinux. SELinux decisions are based fundamentally on labels assigned to these objects and the policy defining how they may interact. In SELinux, a label takes the form: user:role:type:mls_level, where the type is the primary component of the access decisions, which may be modified by the other sections components which make up the label. The objects are mapped to classes and the different types of access for each class are represented by permissions.

The policy rules come in the form: allow domains types:classes permissions;, where:

And so an example use of this would follow the structure:

allow appdomain app_data_file:file rw_file_perms;

This says an application is allowed to read and write files labeled app_data_file. Note that this rule relies upon macros defined in the global_macros file, and other helpful macros can also be found in the te_macros file. Macros are provided for common groupings of classes, permissions and rules, and should be used whenever possible to help reduce the likelihood of failures due to denials on related permissions. During compilation, those overrides are concatenated to the existing SELinux settings and into a single security policy. These overrides add to the base security policy rather than subtract from existing settings.

Use the syntax above to create avc rules that comprise the essence of an SELinux policy. A rule takes the form:

<rule variant> <source_type> <target_type> : <class> <permission>

The rule indicates what should happen when an object labeled with the source_type attempts an action corresponding to permission on an object of class class which has the target_type label. The most common example of one of these rules is an allow rule, e.g.:

allow domain null_device:chr_file { open };

This rule allows a process with source_type of ‘domain’to take the action described by the permission ‘open’ on an object of class ‘chr_file’ that has the target_type label of ‘null_device.’ In practice, this rule may be extended to include other permissions:

allow domain null_device:chr_file { getattr open read ioctl lock append write}; 

When combined with the knowledge that ‘domain’ is a label for all processes and that null_device is the label for the ‘chr_file’ /dev/null, this rule basically permits reading and writing to /dev/null.

A domain generally corresponds to a process and will have a label associated with it.

For example, a typical Android app is running it its own process and has the label of untrusted_app that grants it certain restricted permissions.

Platform apps built into the system run under a separate label and are granted a distinct set of permissions. System apps that are part of the core Android system run under the system_app label for yet another set of privileges.

These generic labels require further specification: