blob: fc632202ea742be9c076debdaa74aaedff78c0e3 [file] [log] [blame]
<html devsite>
<head>
<title>SELinux concepts</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>Review this page to become familiar with SELinux concepts.</p>
<h2 id="mandatory_access_control">Mandatory access control</h2>
<p>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.</p>
<p>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.</p>
<p>Along 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.</p>
<p>In Android 4.3 and higher, 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.</p>
<p>See <a href="/security/selinux/implement.html#use_cases">Use Cases</a>
for more examples of threats and ways to address them with SELinux.</p>
<h2 id="enforcement_levels">Enforcement levels</h2>
<p>SELinux can be implemented in varying modes:</p>
<ul>
<li><em>Permissive</em> - SELinux security policy is not enforced, only logged.
<li><em>Enforcing</em> - Security policy is enforced and logged. Failures
appear as EPERM errors.
</ul>
<p>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.</p>
<h2 id="labels_rules_and_domains">Labels, rules, and domains</h2>
<p>SELinux depends upon <em>labels</em> to match actions and policies. Labels
determine what is allowed. Sockets, files, and processes all have labels in
SELinux. SELinux decisions are based on labels assigned to these objects and
the policy defining how they may interact.</p>
<p>In SELinux, a label takes the form:
<code>user:role:type:mls_level</code>, where the type is the primary component
of the access decisions, which may be modified by the other sections components
that make up the label. The objects are mapped to classes and the different
types of access for each class are represented by permissions. </p>
<p>The policy rules come in the form:
<code>allow <em>domains</em> <em>types</em>:<em>classes</em> <em>permissions</em>;</code>,
where:</p>
<ul>
<li><em>Domain</em> - A label for the process or set of processes. Also
called a domain type as it is just a type for a process.
<li><em>Type</em> - A label for the object (e.g. file, socket) or set of objects.
<li><em>Class</em> - The kind of object (e.g. file, socket) being accessed.
<li><em>Permission</em> - The operation (e.g. read, write) being performed.
</ul>
<p>And so an example use of this would follow the structure:</p>
<pre class="devsite-click-to-copy">
allow appdomain app_data_file:file rw_file_perms;
</pre>
<p>This says that all application domains are allowed to read and write files
labeled <code>app_data_file</code>. Note that this rule relies upon macros
defined in the <code>global_macros</code> file, and other helpful macros can
also be found in the <code>te_macros</code> 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. These macros files are located in the
<a href="https://android.googlesource.com/platform/system/sepolicy/">system/sepolicy</a>
directory. In Android 8.0 and higher, they are in the <code>public</code>
subdirectory with other supported public sepolicy.</p>
<p>In addition to individually listing domains or types in a rule, one can also
refer to a set of domains or types via an <em>attribute</em>. An attribute is
simply a name for a set of domains or types. Each domain or type can be
associated with any number of attributes. When a rule is written that specifies
an attribute name, that name is automatically expanded to the list of domains or
types associated with the attribute. For example, the <em>domain</em> attribute
is associated with all process domains, and the <em>file_type</em> attribute is
associated with all file types.</p>
<p>Use the syntax above to create avc rules that comprise the essence of an
SELinux policy. A rule takes the form:
<pre class="devsite-click-to-copy">
<var>RULE_VARIANT SOURCE_TYPES TARGET_TYPES</var> : <var>CLASSES PERMISSIONS</var>
</pre>
<p>The rule indicates what should happen when a subject labeled with any of the
<em>source_types</em> attempts an action corresponding to any of the
<em>permissions</em> on an object with any of the class <em>classes</em> that
has any of the <em>target_types</em> label. The most common example of one of
these rules is an allow rule, such as:</p>
<pre class="devsite-click-to-copy">
allow domain null_device:chr_file { open };
</pre>
<p>
This rule allows a process with any <em>domain</em> associated with the
<code>domain</code> attribute to take the action described by the
<em>permission</em> <code>open</code> on an object of <em>class</em>
<code>chr_file</code> (character device file) that has the <em>target_type</em>
label of <code>null_device</code>. In practice, this rule may be extended to
include other permissions:</p>
<pre class="devsite-click-to-copy">
allow domain null_device:chr_file { getattr open read ioctl lock append write};
</pre>
<p>When combined with the knowledge that <code>domain</code> is an attribute
assigned to all process domains and that <code>null_device</code> is the label
for the character device <code>/dev/null</code>, this rule basically permits
reading and writing to <code>/dev/null</code>.</p>
<p>A <em>domain</em> generally corresponds to a process and has a label
associated with it.</p>
<p>For example, a typical Android app is running in its own process and has the
label of <code>untrusted_app</code> that grants it certain restricted permissions.</p>
<p>Platform apps built into the system run under a separate label and are granted
a distinct set of permissions. System UID apps that are part of the core Android
system run under the <code>system_app</code> label for yet another set of
privileges.</p>
<p>Access to the following generic labels should never be directly allowed to
domains; instead, a more specific type should be created for the object or
objects:</p>
<ul>
<li><code>socket_device</code></li>
<li><code>device</code></li>
<li><code>block_device</code></li>
<li><code>default_service</code></li>
<li><code>system_data_file</code></li>
<li><code>tmpfs</code></li>
</ul>
</body>
</html>