blob: ad06feed80da952d59acfc8ddfdc67c06598f993 [file] [log] [blame]
page.title=Validating Security-Enhanced Linux in Android
@jd:body
<!--
Copyright 2014 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.
-->
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol id="auto-toc">
</ol>
</div>
</div>
<h2 id="introduction">Introduction</h2>
<p>
As part of the Android <a href="{@docRoot}devices/tech/security/index.html">security
model</a>, Android uses Security-Enhanced Linux (SELinux) to enforce Mandatory
Access Control (MAC) over all processes, even processes running
with root/superuser privileges (a.k.a. Linux capabilities). SELinux enhances
Android security, and contributions to it have been made by a number of
companies and organizations; all Android code and contributors are publicly
available for review on
<a href="https://android.googlesource.com/">android.googlesource.com</a>. With
SELinux, Android can better protect and confine system services, control access
to application data and system logs, reduce the effects of malicious software,
and protect users from potential flaws in code on mobile devices.
</p>
<p>
Android includes SELinux in enforcing mode and a corresponding security policy
that works by default across the <a
href="https://android.googlesource.com/">Android Open Source
Project</a>. In enforcing mode, illegitimate
actions are prevented and all potential violations are logged by the kernel to
<code>dmesg</code>. Android device manufacturers should gather information about
errors so they may refine their software and SELinux policies before enforcing
them.
</p>
<h2 id="background">Background</h2>
<p>
SELinux can operate in one of two global modes: permissive mode, in
which permission denials are logged but not enforced, and enforcing
mode, in which permission denials are both logged and
enforced. SELinux also supports a per-domain permissive mode in which
specific domains (processes) can be made permissive while placing the
rest of the system in global enforcing mode. A domain is simply a
label identifying a process or set of processes in the security
policy, where all processes labeled with the same domain are treated
identically by the security policy. Per-domain permissive mode enables
incremental application of SELinux to an ever-increasing portion of
the system. Per-domain permissive mode also enables policy
development for new services while keeping the rest of the system
enforcing.
</p>
<p>
In Android 4.3, SELinux was fully permissive. In Android 4.4, SELinux
was made enforcing for the domains for several root processes:
<code>installd</code>, <code>netd</code>, <code>vold</code> and
<code>zygote</code>. <em>All other processes, including other
services and all apps, remain in permissive mode to allow further
evaluation and prevent failures in Android 4.4. Still, an errant
application could trigger an action in a root process that is not
allowed, thereby causing the process or the application to crash.</em>
</p>
<p>
For this reason, device manufacturers should retain the default settings
provided by Android and limit enforcing mode to system services only until
they've resolved issues reported in dmesg. That said, device manufacturers may
need to augment their SELinux implementation to account for their additions and
other changes to the operating system. See the <em>Customization</em> section for
instructions.
</p>
<h2 id="mac">Mandatory access control</h2>
<p>
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.
</p>
<p>
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.
</p>
<p>
See the <em>Use Cases</em> section for more examples of threats and ways to
address them with SELinux.
</p>
<h2 id="implementation">Implementation</h2>
<p>
Android's SELinux implementation is in enforcing mode - rather than the
non-functional disabled mode or the notification-only permissive mode - to act
as a reference and facilitate testing and development. Although enforcing mode
is set globally, please remember this can be overridden on a per-domain basis
as is in the case of the application domain.
</p>
<p>
SELinux for Android is accompanied by everything you need to enable SELinux
now. You merely need to integrate the <a
href="https://android.googlesource.com/kernel/common/">latest Android
kernel</a> and then incorporate the files found in the
<a
href="https://android.googlesource.com/platform/external/sepolicy/">
external/sepolicy</a> directory:<br/>
<a
href="https://android.googlesource.com/kernel/common/">
https://android.googlesource.com/kernel/common/</a>
<br/>
<a
href="https://android.googlesource.com/platform/external/sepolicy/">
https://android.googlesource.com/platform/external/sepolicy/</a>
</p>
<p>
Those files when compiled comprise the SELinux kernel security policy and cover
the upstream Android operating system. You should not need to modify
the <root>external/sepolicy</root> files directly. Instead, add your own
device-specific policy files within the
<root>/device/manufacturer/device-name/sepolicy directory.
</p>
<p>
Then just update your <code>BoardConfig.mk</code> makefile - located in the
<device-name> directory containing the sepolicy subdirectory - to reference the
sepolicy subdirectory and any policy file once created, as shown below. The
BOARD_SEPOLICY variables and their meaning is documented in the
external/sepolicy/README file.
</p>
<pre>
BOARD_SEPOLICY_DIRS += \
&lt;root&gt;/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
</pre>
<p>
After rebuilding your device, it is enabled with SELinux. You can now either
customize your SELinux policies to accommodate your own additions to the Android
operating system as described in the <em>Customization</em> section or verify
your existing setup as covered in the <em>Validation</em> section.
</p>
<h2 id="customization">Customization</h2>
<p>
Once you've integrated this base level of functionality and thoroughly analyzed
the results, you may add your own policy settings to cover your customizations
to the Android operating system. Of course, these policies must still meet the
<a href="http://source.android.com/compatibility/index.html">Android
Compatibility
program</a> requirements and
not remove the default SELinux settings.
</p>
<p>
Manufacturers should not remove existing security settings. Otherwise, they risk
breaking the Android SELinux implementation and the applications it governs.
This includes third-party applications that will likely need to be improved to
be compliant and operational. Applications must require no modification to
continue functioning on SELinux-enabled devices.
</p>
<p>
See the <em>Kernel Security Features</em> section of the Android Compatibility
Definition document for specific requirements:<br/>
<a
href="http://source.android.com/compatibility/index.html">
http://source.android.com/compatibility/index.html</a>
</p>
<p>
SELinux uses a whitelist approach, meaning all access must be explicitly allowed
in policy in order to be granted. Since Android's default SELinux policy already
supports the Android Open Source Project, OEMs are not required to modify
SELinux settings in any way. If they do customize SELinux settings, they should
take great care not to break existing applications. Here is how we recommend
proceeding:
</p>
<ol>
<li>Use the <a href="https://android.googlesource.com/kernel/common/">latest
Android
kernel</a>.</li>
<li>Adopt the <a
href="http://en.wikipedia.org/wiki/Principle_of_least_privilege">principle of
least
privilege</a>.</li>
<li>Address only your own additions to Android. The default policy works with
the
<a href="https://android.googlesource.com/">Android Open Source Project</a>
codebase
automatically.</li>
<li>Compartmentalize software components into modules that conduct singular
tasks.</li>
<li>Create SELinux policies that isolate those tasks from unrelated
functions.</li>
<li>Put those policies in *.te files (the extension for SELinux policy source
files) within the <root>/device/manufacturer/device-name/sepolicy
directory and use BOARD_SEPOLICY variables to include them in your build.</li>
<li>Make new domains permissive initially. In Android 4.4 and earlier, this
is done using a permissive declaration. In later versions of Android,
per-domain permissive mode is specified using the permissive_or_unconfined()
macro.</li>
<li>Analyze results and refine your domain definitions.</li>
<li>Remove the permissive declaration when no further denials appear
in userdebug builds.</li>
</ol>
<p>
Once integrated, OEM Android development should include a step to ensure
SELinux
compatibility going forward. In an ideal software development process, SELinux
policy changes only when the software model changes and not the actual
implementation.
</p>
<p>
As device manufacturers begin to customize SELinux, they should first audit
their additions to Android. If they've added a component that conducts a new
function, the manufacturers will need to ensure the component meets the security
policy applied by Android, as well as any associated policy crafted by the OEM,
before turning on enforcing mode.
</p>
<p>
To prevent unnecessary issues, it is better to be overbroad and over-compatible
than too restrictive and incompatible, which results in broken device functions.
Conversely, if a manufacturer's changes will benefit others, it should supply
the modifications to the default SELinux policy as a
<a href="http://source.android.com/source/submit-patches.html">patch</a>. If the
patch is
applied to the default security policy, the manufacturer will no longer need to
make this change with each new Android release.
</p>
<h2 id="use-cases">Use Cases</h2> <p>Here are specific examples of exploits to
consider when crafting your own software and associated SELinux policies:</p>
<p><strong>Symlinks</strong> - Because symlinks appear as files, they are often
read just as that. This can lead to exploits. For instance, some privileged
components such as <code>init</code> change the permissions of certain files,
sometimes to be excessively open.</p>
<p>Attackers might then replace those files with symlinks to code they control,
allowing the attacker to overwrite arbitrary files. But if you know your
application will never traverse a symlink, you can prohibit it from doing so
with SELinux.</p>
<p><strong>System files</strong> - Consider the class of system files that
should only be modified by the system server. Still, since <code>netd</code>,
<code>init</code>, and <code>vold</code> run as root, they can access those
system files. So if <code>netd</code> became compromised, it could compromise
those files and potentially the system server itself.</p>
<p>With SELinux, you can identify those files as system server data files.
Therefore, the only domain that has read/write access to them is system server.
Even if <code>netd</code> became compromised, it could not switch domains to the
system server domain and access those system files although it runs as root.</p>
<p><strong>App data</strong> - Another example is the class of functions that
must run as root but should not get to access app data. This is incredibly
useful as wide-ranging assertions can be made, such as certain domains
unrelated to application data being prohibited from accessing the internet.</p>
<p><strong>setattr</strong> - For commands such as <code>chmod</code> and
<code>chown</code>, you could identify the set of files where the associated
domain can conduct <code>setattr</code>. Anything outside of that could be
prohibited from these changes, even by root. So an application might run
<code>chmod</code> and <code>chown</code> against those labeled app_data_files
but not shell_data_files or system_data_files.</p>
<h2 id="related-files">Related Files</h2>
<p>This section serves to guide you once you&rsquo;ve decided to
customize the SELinux policy settings. See the <em>Customization</em> section
for steps. We recommend device manufacturers start with the default Android
SELinux policy and make the minimum possible set of changes to address their
additions to Android. Existing Android SELinux policy files are found in the
root of the <a
href="https://android.googlesource.com/platform/external/sepolicy/">
external/sepolicy</a> directory.</p>
<p>Android upgraded its SELinux policy version to allow the SELinux mode to be
set to permissive on a per-domain basis. For example, if you run all of your
applications in a single domain, you could set that domain to be permissive and
then have all other functions and their domains set to enforcing. Domains are
associated with applications by the key used to sign each application. The
mapping of app certificates to domains is specified via the
mac_permissions.xml and seapp_contexts configuration files.</p>
<p>Here are the files you must create or edit in order to customize SELinux:</p>
<ul>
<li>
<p><em>New SELinux policy source (*.te) files</em> - Located in the
&lt;root&gt;/device/manufacturer/device-name/sepolicy directory These files
define domains and their labels. The new policy files get concatenated with the
existing policy files during compilation into a single SELinux kernel policy
file.</p>
<p><strong>Important</strong>:Do not alter the app.te file provided by the
Android Open Source Project. Doing so risks breaking all third-party
applications.
</p>
</li>
<li>
<p><em>Updated <code>BoardConfig.mk</code> makefile</em> - Located in the
&lt;device-name&gt; directory containing the sepolicy subdirectory. It must be
updated to reference the sepolicy subdirectory once created if it wasn&rsquo;t
in initial implementation.</p> </li>
<li>
<p><em>Updated <code>file_contexts</code></em> - Located in
the sepolicy subdirectory. It labels files and is managed in the userspace. As
you create new policies, update this file to reference them. In order to apply
new <code>file_contexts</code>, you must run <code>restorecon</code> on the file
to be relabeled.</p>
</li> </ul>
<p>The remaining files in the sepolicy directory are either auto-generated or
should remain static. The policy rules come in the form: allow <em>domains</em>
<em>types</em>:<em>classes</em> <em>permissions</em>;, where:</p>
<ul>
<li>
<p><em>Domain</em> - A label for the process or set of processes.
</p></li>
<li>
<p><em>Type</em> - A label for the object (e.g. file, socket) or set of objects.
</p></li>
<li>
<p><em>Class</em> - The kind of object (e.g. file, socket) being accessed.
</p></li>
<li>
<p><em>Permission</em> - The operation (e.g. read, write) being performed.
</p></li>
<p>And so an example use of this would follow the structure:<br>
<code>allow appdomain app_data_file:file rw_file_perms;</code></p>
<p>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.</p>
<p>Once the new policy files and <code>BoardConfig.mk</code> updates are in
place, the new policy settings are automatically built into the final kernel
policy file.</p>
<h2 id="validation">Validation</h2> <p>Android strongly encourages OEMs to test
their SELinux implementations thoroughly. As manufacturers implement SELinux,
they should initially release their own policies in permissive mode. If
possible, apply the new policy to a test pool of devices first.</p>
<p>Once applied, make sure SELinux is running in the correct mode on the device
by issuing the command: <code>getenforce</code></p>
<p>This will print the global SELinux mode: either Disabled, Enforcing, or
Permissive.
Please note, this command shows only the global SELinux mode. To determine the
SELinux mode for each domain, you must examine the corresponding files.</p>
<p>Then check for errors. Errors are routed as event logs to <code>dmesg</code>
and viewable locally on the device. Manufacturers should examine the SELinux
output to <code>dmesg</code> on these devices and refine settings prior to
public release in permissive mode and eventual switch to enforcing mode. It is
possible to capture the ongoing denial logs by running
<code>cat /proc/kmsg</code> or to capture denial logs from the previous boot by
running <code>cat /proc/last_kmsg</code>.</p>
<p>With this output, manufacturers can readily identify when system users or
components are in violation of SELinux policy. Manufacturers can then repair
this bad behavior, either by changes to the software, SELinux policy, or
both.</p>
<p>Specifically, these log messages indicate what processes would fail
under enforcing mode and why. Here is an example:</p>
<pre>
denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd"
scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
</pre>
<p>Interpret this output like so:</p>
<ul>
<li>The { connectto } above represents the action being taken. Together with the
tclass at the end (unix_stream_socket) it tells you roughly what was being done
to what. In this case, something was trying to connect to a unix stream
socket.</li>
<li>The scontext (u:r:shell:s0) tells you what context initiated the action. In
this case this is something running as the shell.</li>
<li>The tcontext (u:r:netd:s0) tells you the context of the actions target. In
this case, thats a unix_stream_socket owned by netd.</li>
<li>The comm="ping" at the top gives you an additional hint about what was being
run at the time the denial was generated. In this case, its a pretty good
hint.</li>
</ul>
<p>Android is taking this information, analyzing
it and refining its default security policy so that it works on a wide range of
Android devices with little customization. With this policy, OEMs must only
accommodate their own changes to the Android operating system.</p>
<p>Then run the SELinux-enabled devices through the <a
href="{@docRoot}compatibility/cts-intro.html">Android
Compatibility Test Suite</a> (CTS).</p> <p>As said, any new policies must still
meet the <a href="{@docRoot}compatibility/index.html">Android
Compatibility program</a> requirements.</p>
<p>Finally, if possible, turn on enforcing mode internally (on devices of
employees) to raise the visibility of failures. Identify any user issues and
resolve them. </p> <h2 id="help">Help</h2> Device manufacturers are strongly
encouraged to work with their Android account managers to analyze SELinux
results and improve policy settings. Over time, Android intends to support
common manufacturer additions in its default SELinux policy. For more
information, contact security@android.com.