| page.title=Validating Security-Enhanced Linux in Android |
| @jd:body |
| |
| <!-- |
| Copyright 2013 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 apply access |
| control policies. 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 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> |
| Please note, Android upgraded its SELinux policy version to allow the SELinux |
| mode to be set on a per-domain basis. For example, if you run all of your |
| applications on a single domain, you could set that domain to be permissive and |
| then have all other functions and their domains set to enforcement. Domains are |
| associated with applications by the key used to sign each application. This |
| setting is made at the top of each SELinux policy source (*.te) file. |
| </p> |
| <p> |
| Android follows this model of isolating applications to a single domain. With |
| this, only the root domain and root-level processes (such as <code>initd</code>, |
| <code>installd</code> and |
| <code>vold</code>) are now set to enforcing mode. <em>The application domain remains in |
| permissive mode to allow further evaluation and prevent failures. Still, an |
| errant application could trigger an action in the root domain that is not |
| allowed, thereby causing 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 the root domain 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 user role assigned the root privilege can write to |
| only those specified in the associated policy. In this way, root 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/">platform/external/sepolicy</a> |
| directory (where examples can also be found):<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. Place those files within the |
| <root>/device/manufacturer/device-name/sepolicy directory.<br/> |
| Then just update your <code>BoardConfig.mk</code> makefile - located in the <device-name> |
| directory containing the sepolicy subdirectory - to reference the sepolicy |
| subdirectory once created, like so: |
| </p> |
| |
| <pre> |
| BOARD_SEPOLICY_DIRS += \ |
| <root>/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 it grants special privileges based |
| upon role. 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.</li> |
| <li>Release your SELinux implementation in permissive mode first.</li> |
| <li>Analyze results and refine policy settings.</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 enforcement. |
| </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’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/">platform/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 on a single domain, you could set that domain to be permissive and |
| then have all other functions and their domains set to enforcement. Domains are |
| associated with applications by the key used to sign each application. This |
| setting is made at the top of each SELinux policy source (*.te) file.</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 |
| <root>/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 |
| <device-name> directory containing the sepolicy subdirectory. It must be |
| updated to reference the sepolicy subdirectory once created if it wasn’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 files come in the form: allow, domain, and |
| context, for a set of actions:</p> |
| |
| <ul> |
| <li> |
| <p><em>Allow</em> - Gives the role permission to carry out the action described |
| in the context within the specified domain.</p> </li> |
| <li> |
| <p><em>Domain</em> - Domain |
| represents scope of the rule and gets converted to a security identifier (SID) |
| in the kernel.</p> </li> |
| <li> |
| <p><em>Context</em> - An identifier for the rule, this is converted |
| to an integer in the kernel.</p> </li> </ul> |
| |
| <p>And so the 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. 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 get automatically uploaded to the device.</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.</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 roles and processes would fail |
| under policy enforcement 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 action’s target. In |
| this case, that’s 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, it’s 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 enforcement 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 <a |
| href="mailto:security@google.com?subject=se-linux">security@android.com</a>. |