You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
12 KiB
302 lines
12 KiB
<html devsite> |
|
<head> |
|
<title>Customizing SELinux</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>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="/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>When embarking upon customizing SELinux, manufacturers should remember to:</p> |
|
|
|
<ul> |
|
<li>Write SELinux policy for all new daemons |
|
<li>Use predefined domains whenever appropriate |
|
<li>Assign a domain to any process spawned as an <code>init</code> service |
|
<li>Become familiar with the macros before writing policy |
|
<li>Submit changes to core policy to AOSP |
|
</ul> |
|
|
|
<p>And not to:</p> |
|
|
|
<ul> |
|
<li>Create incompatible policy |
|
<li>Allow end user policy customization |
|
<li>Allow MDM policy customizations |
|
<li>Scare users with policy violations |
|
<li>Add backdoors |
|
</ul> |
|
|
|
<p>See the <em>Kernel Security Features</em> section of the <a href="/compatibility/android-cdd.pdf">Android Compatibility Definition document</a> for specific requirements.</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>Adopt the <a href="http://en.wikipedia.org/wiki/Principle_of_least_privilege">principle of least privilege</a>. |
|
<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>Compartmentalize software components into modules that conduct singular tasks. |
|
<li>Create SELinux policies that isolate those tasks from unrelated functions. |
|
<li>Put those policies in *.te files (the extension for SELinux policy source |
|
files) within the <code>/device/manufacturer/device-name/sepolicy</code> directory and use |
|
<code>BOARD_SEPOLICY</code> variables to include them in your build. |
|
<li>Make new domains permissive initially. This is done by |
|
using a permissive declaration in the domain's .te file. |
|
<li>Analyze results and refine your domain definitions. |
|
<li>Remove the permissive declaration when no further denials appear in userdebug |
|
builds. |
|
</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="/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=example_policy_statements>Example policy statements</h2> |
|
|
|
<p>First, note SELinux is based upon the <a href="https://www.gnu.org/software/m4/manual/index.html">M4</a> computer language and therefore supports a variety of macros to save time.</p> |
|
|
|
<p>In the following example, all domains are granted access to read from or write to <code>/dev/null</code> and read from <code>/dev/zero</code>.</p> |
|
|
|
<pre class="devsite-click-to-copy"> |
|
# Allow read / write access to /dev/null |
|
allow domain null_device:chr_file { getattr open read ioctl lock append write}; |
|
|
|
# Allow read-only access to /dev/zero |
|
allow domain zero_device:chr_file { getattr open read ioctl lock }; |
|
</pre> |
|
|
|
|
|
<p>This same statement can be written with SELinux <code>*_file_perms</code> macros (shorthand):</p> |
|
|
|
<pre class="devsite-click-to-copy"> |
|
# Allow read / write access to /dev/null |
|
allow domain null_device:chr_file rw_file_perms; |
|
|
|
# Allow read-only access to /dev/zero |
|
allow domain zero_device:chr_file r_file_perms; |
|
</pre> |
|
|
|
<h2 id=example_policy>Example policy</h2> |
|
|
|
<p>Here is a complete example policy for DHCP, which we examine below:</p> |
|
|
|
<pre class="devsite-click-to-copy"> |
|
type dhcp, domain; |
|
permissive dhcp; |
|
type dhcp_exec, exec_type, file_type; |
|
type dhcp_data_file, file_type, data_file_type; |
|
|
|
init_daemon_domain(dhcp) |
|
net_domain(dhcp) |
|
|
|
allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service |
|
}; |
|
allow dhcp self:packet_socket create_socket_perms; |
|
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write }; |
|
allow dhcp shell_exec:file rx_file_perms; |
|
allow dhcp system_file:file rx_file_perms; |
|
# For /proc/sys/net/ipv4/conf/*/promote_secondaries |
|
allow dhcp proc_net:file write; |
|
allow dhcp system_prop:property_service set ; |
|
unix_socket_connect(dhcp, property, init) |
|
|
|
type_transition dhcp system_data_file:{ dir file } dhcp_data_file; |
|
allow dhcp dhcp_data_file:dir create_dir_perms; |
|
allow dhcp dhcp_data_file:file create_file_perms; |
|
|
|
allow dhcp netd:fd use; |
|
allow dhcp netd:fifo_file rw_file_perms; |
|
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write }; |
|
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket |
|
netlink_nflog_socket } { read write }; |
|
</pre> |
|
|
|
<p>Let’s dissect the example:</p> |
|
|
|
<p>In the first line, the type declaration, the DHCP daemon inherits from the base |
|
security policy (<code>domain</code>). From the previous statement examples, we know DHCP can read from and write |
|
to <code>/dev/null</code>.</p> |
|
|
|
<p>In the second line, DHCP is identified as a permissive domain.</p> |
|
|
|
<p>In the <code>init_daemon_domain(dhcp)</code> line, the policy states DHCP is spawned from <code>init</code> and is allowed to communicate with it.</p> |
|
|
|
<p>In the <code>net_domain(dhcp)</code> line, the policy allows DHCP to use common network functionality from the <code>net</code> domain such as reading and writing TCP packets, communicating over sockets, and conducting DNS requests.</p> |
|
|
|
<p>In the line <code>allow dhcp proc_net:file write;</code>, the policy states DHCP can write to specific files in <code>/proc</code>. This line demonstrates SELinux’s fine-grained file labeling. It uses the <code>proc_net</code> label to limit write access to only the files under <code>/proc/sys/net</code>.</p> |
|
|
|
<p>The final block of the example starting with <code>allow dhcp netd:fd use;</code> depicts how applications may be allowed to interact with one another. The |
|
policy says DHCP and netd may communicate with one another via file |
|
descriptors, FIFO files, datagram sockets, and UNIX stream sockets. DHCP may |
|
only read to and write from the datagram sockets and UNIX stream sockets and |
|
not create or open them.</p> |
|
|
|
<h2 id=available_controls>Available controls</h2> |
|
|
|
<table> |
|
<tr> |
|
<td> |
|
<p><strong>Class</strong></p> |
|
</td> |
|
<td> |
|
<p><strong>Permission</strong></p> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>file</p> |
|
</td> |
|
<td> |
|
<pre> |
|
ioctl read write create getattr setattr lock relabelfrom relabelto append |
|
unlink link rename execute swapon quotaon mounton</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>directory</p> |
|
</td> |
|
<td> |
|
<pre> |
|
add_name remove_name reparent search rmdir open audit_access execmod</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>socket</p> |
|
</td> |
|
<td> |
|
<pre> |
|
ioctl read write create getattr setattr lock relabelfrom relabelto append bind |
|
connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg |
|
name_bind</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>filesystem</p> |
|
</td> |
|
<td> |
|
<pre> |
|
mount remount unmount getattr relabelfrom relabelto transition associate |
|
quotamod quotaget</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>process</p> |
|
</td> |
|
<td> |
|
<pre> |
|
fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched |
|
getsession getpgid setpgid getcap setcap share getattr setexec setfscreate |
|
noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem |
|
execstack execheap setkeycreate setsockcreate</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>security</p> |
|
</td> |
|
<td> |
|
<pre> |
|
compute_av compute_create compute_member check_context load_policy |
|
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot |
|
read_policy</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p>capability</p> |
|
</td> |
|
<td> |
|
<pre> |
|
chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap |
|
linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock |
|
ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin |
|
sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write |
|
audit_control setfcap</pre> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<p><strong>MORE</strong></p> |
|
</td> |
|
<td> |
|
<p><strong>AND MORE</strong></p> |
|
</td> |
|
</tr> |
|
</table> |
|
|
|
<h2 id=neverallow>neverallow rules</h2> |
|
|
|
<p>SELinux <code>neverallow</code> rules prohibit behavior that should never occur. |
|
With <a href="/compatibility/index.html">compatibility</a> testing, |
|
SELinux <code>neverallow</code> rules are now enforced across partner devices.</p> |
|
|
|
<p>The following guidelines are intended to help manufacturers avoid errors |
|
related to <code>neverallow</code> rules during customization. The rule numbers |
|
used here correspond to Android 5.1 and are subject to change by release.</p> |
|
|
|
<p>Rule 48: <code>neverallow { domain -debuggerd -vold -dumpstate |
|
-system_server } self:capability sys_ptrace;</code><br> |
|
See the man page for <code>ptrace</code>. The <code>sys_ptrace</code> |
|
capability grants the ability to <code>ptrace</code> any process, which allows a great deal |
|
of control over other processes and should belong only to designated system |
|
components, outlined in the rule. The need for this capability often indicates |
|
the presence of something that is not meant for user-facing builds or |
|
functionality that isn’t needed. Remove the unnecessary component.</p> |
|
|
|
<p>Rule 76: <code>neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;</code><br> |
|
This rule is intended to prevent the execution of arbitrary code on the system. |
|
Specifically, it asserts that only code on <code>/system</code> gets executed, |
|
which allows security guarantees thanks to mechanisms such as verified boot. |
|
Often, the best solution when encountering a problem with this |
|
<code>neverallow</code> rule is to move the offending code to the |
|
<code>/system</code> partition.</p> |
|
|
|
</body> |
|
</html>
|
|
|