Home | History | Annotate | Download | only in selinux
      1 <html devsite>
      2   <head>
      3     <title>Writing SELinux Policy</title>
      4     <meta name="project_path" value="/_project.yaml" />
      5     <meta name="book_path" value="/_book.yaml" />
      6   </head>
      7   <body>
      8   <!--
      9       Copyright 2017 The Android Open Source Project
     10 
     11       Licensed under the Apache License, Version 2.0 (the "License");
     12       you may not use this file except in compliance with the License.
     13       You may obtain a copy of the License at
     14 
     15           http://www.apache.org/licenses/LICENSE-2.0
     16 
     17       Unless required by applicable law or agreed to in writing, software
     18       distributed under the License is distributed on an "AS IS" BASIS,
     19       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     20       See the License for the specific language governing permissions and
     21       limitations under the License.
     22   -->
     23 
     24 
     25 
     26 
     27 
     28 <p>The Android Open Source Project (AOSP) provides a solid base policy for the
     29 applications and services that are common across all Android devices.
     30 Contributors to AOSP regularly refine this policy. The core policy is expected
     31 to make up about 90&ndash;95% of the final on-device policy with device-specific
     32 customizations making up the remaining 5&ndash;10%. This article focuses on these
     33 device-specific customizations, how to write device-specific policy, and some
     34 of the pitfalls to avoid along the way.</p>
     35 
     36 <h2 id=device_bringup>Device bringup</h2>
     37 
     38 <p>While writing device-specific policy, progress through the following steps in order.</p>
     39 
     40 <h3 id=run_in_permissive_mode>Run in permissive mode</h3>
     41 
     42 
     43 <p>When a device is in <a href="index.html#background">permissive mode</a>,
     44 denials are logged but not enforced. Permissive mode is important for two
     45 reasons:</p>
     46 
     47 <ol>
     48   <li> Permissive mode ensures that policy bringup does not delay other early device
     49        bringup tasks.
     50   <li> An enforced denial may mask other denials. For example, file access
     51        typically entails a directory search, file open, then file read. In
     52        enforcing mode, only the directory search denial would occur. Permissive
     53        mode ensures all denials are seen.
     54 </ol>
     55 
     56 <p>The simplest way to put a device into permissive mode is via the
     57 <a href="validate.html#switching_to_permissive">kernel command line</a>. This
     58 can be added to the devices BoardConfig.mk file:
     59 <code>platform/device/&lt;vendor&gt;/&lt;target&gt;/BoardConfig.mk</code>.
     60 After modifying the command line, perform <code>make clean</code>, then
     61 <code>make bootimage</code>, and flash the new boot image.</p>
     62 
     63 <p>After that, confirm permissive mode with:</p>
     64 
     65 <pre class="devsite-terminal devsite-click-to-copy">
     66 adb getenforce
     67 </pre>
     68 
     69 
     70 <p>Two weeks is a reasonable amount of time to be in global permissive mode. After
     71 addressing the majority of denials, move back into enforcing mode and address
     72 bugs as they come in. Domains still producing denials or services still under
     73 heavy development can be temporarily put into permissive mode, but move them
     74 back to enforcing mode as soon as possible.</p>
     75 
     76 <h3 id=enforce_early>Enforce early</h3>
     77 
     78 
     79 <p>In enforcing mode, denials are both logged and enforced. It is a best practice
     80 to get your device into enforcing mode as early as possible. Waiting to create
     81 and enforce device-specific policy often results in a buggy product and a bad
     82 user experience. Start early enough to participate in
     83 <a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfooding</a>
     84 and ensure full test coverage of functionality in real world usage. Starting
     85 early ensures security concerns inform design decisions. Conversely, granting
     86 permissions based solely on observed denials is an unsafe approach. Use this
     87 time to perform a security audit of the device and file bugs against behavior
     88 that should not be allowed.</p>
     89 
     90 <h3 id=remove_or_delete_existing_policy>Remove or delete existing policy</h3>
     91 
     92 
     93 <p>There are a number of good reasons to create device-specific policy from
     94 scratch on a new device, which include:</p>
     95 
     96 <ul>
     97   <li> Security auditing
     98   <li> <a href="#overuse_of_negation">Overly permissive policy</a>
     99   <li> <a href="#policy_size_explosion">Policy size reduction</a>
    100   <li> Dead policy
    101 </ul>
    102 
    103 <h3 id=address_denials_of_core_services>Address denials of core services</h3>
    104 
    105 
    106 <p>Denials generated by core services are typically addressed by file labeling.
    107 For example:</p>
    108 
    109 <pre>
    110 avc: denied { open } for pid=1003 comm=mediaserver path="/dev/kgsl-3d0
    111 dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
    112 tclass=chr_file permissive=1
    113 avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
    114 scontext=u:r:mediaserver:s0
    115 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
    116 </pre>
    117 
    118 
    119 <p>is completely addressed by properly labeling <code>/dev/kgsl-3d0</code>. In
    120 this example, <code>tcontext</code> is <code>device</code>. This represents a
    121 default context where everything in <code>/dev</code> receives the
    122 <a href="https://android.googlesource.com/platform/external/sepolicy/+/marshmallow-dev/file_contexts#31">
    123 device</a> label unless a more specific label is assigned. Simply accepting
    124 the output from <a href="validate.html#using_audit2allow">audit2allow</a> here
    125 would result in an incorrect and overly permissive rule.</p>
    126 
    127 <p>To solve this kind of problem, give the file a more specific label, which in
    128 this case is
    129 <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#1">
    130 gpu_device</a>. No further permissions are needed as the
    131 <a href="https://android.googlesource.com/platform/external/sepolicy/+/marshmallow-dev/mediaserver.te#24">
    132 mediaserver already has necessary permissions</a> in core policy to access the
    133 gpu_device.</p>
    134 
    135 <p>Other device-specific files that should be labeled with types predefined in
    136 core policy:</p>
    137 
    138 <ol>
    139   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#31">
    140        block devices</a>
    141   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#80">
    142        audio devices</a>
    143   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#21">
    144        video devices</a>
    145   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#89">
    146        sensors</a>
    147   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#8">
    148        nfc</a>
    149   <li> gps_device
    150   <li> <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/file_contexts#139">
    151        files in /sys</a>
    152   <li> files in /proc
    153 </ol>
    154 
    155 <p>In general, granting permissions to default labels is wrong. Many of these
    156 permissions are disallowed by <a href="customize.html#neverallow">neverallow</a>
    157 rules, but even when not explicitly disallowed, best practice is to provide a
    158 specific label.</p>
    159 
    160 <h3 id=label_new_services_and_address_denials>Label new services and address denials</h3>
    161 
    162 
    163 <p>Init-launched services are required to run in their own SELinux domains. The
    164 following example puts service foo into its own SELinux domain and grants it
    165 permissions.</p>
    166 
    167 <p>The service is launched in our devices <code>init.&lt;target&gt;.rc</code> file as:</p>
    168 
    169 <pre class="devsite-click-to-copy">
    170 service foo /system/bin/foo
    171     class core
    172 </pre>
    173 
    174 <ol>
    175   <li>Create a new domain "foo"<br />
    176 
    177       <p>Create the file <code>device/&lt;oem&gt;/&lt;target&gt;/sepolicy/foo.te</code>
    178       with the following contents:</p>
    179 
    180 <pre class="devsite-click-to-copy">
    181 # foo service
    182 type foo, domain;
    183 type foo_exec, exec_type, file_type;
    184 
    185 init_daemon_domain(foo)
    186 </pre>
    187 
    188 
    189       <p>This is the initial template for the foo SELinux domain, to which you
    190          can add rules based on the specific operations performed by that executable.</p>
    191   </li>
    192 
    193   <li>Label <code>/system/bin/foo</code><br />
    194 
    195       <p>Add the following to <code>device/&lt;oem&gt;/&lt;target&gt;/sepolicy/
    196          file_contexts</code>:</p>
    197 
    198 <pre class="devsite-click-to-copy">
    199 /system/bin/foo   u:object_r:foo_exec:s0
    200 </pre>
    201 
    202 
    203       <p>This makes sure the executable is properly labeled so SELinux runs the
    204          service in the proper domain.</p>
    205   </li>
    206 
    207   <li>Build and flash the boot and system images.</li>
    208 
    209   <li>Refine the SELinux rules for the domain.<br />
    210 
    211       <p>Use denials to determine the required permissions. The
    212          <a href="validate.html#using_audit2allow">audit2allow</a> tool provides
    213          good guidelines, but only use it to inform policy writing. Do
    214          not just copy the output.</p>
    215   </li>
    216 </ol>
    217 
    218 <h3 id=enforcing_mode>Switch back to enforcing mode</h3>
    219 
    220 
    221 <p>Its fine to troubleshoot in permissive mode, but switch back to enforcing
    222 mode as early as possible and try to remain there.</p>
    223 
    224 <h2 id=common_mistakes>Common mistakes</h2>
    225 
    226 
    227 <p>Here are a few solutions for common mistakes that happen when writing
    228 device-specific policies.</p>
    229 
    230 <h3 id=overuse_of_negation>Overuse of negation</h3>
    231 
    232 
    233 <p>The following example rule is like locking the front door but leaving the
    234 windows open:</p>
    235 
    236 <pre>allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms</pre>
    237 
    238 <p>The intent is clear: everyone but third-party apps may have access to the debug
    239 device. </p>
    240 
    241 <p>The rule is flawed in a few of ways. The exclusion of <code>untrusted_app</code>
    242 is trivial to work around because all apps may optionally run services in the
    243 <code>isolated_app</code> domain. Likewise, if new domains for third-party apps
    244 are added to AOSP, they will also have access to <code>scary_debug_device</code>.
    245 The rule is overly permissive. Most domains will not benefit from having
    246 access to this debugging tool. The rule should have been written to allow only
    247 the domains that require access. </p>
    248 
    249 <h3 id=debugging_features_in_production>Debugging features in production</h3>
    250 
    251 
    252 <p>Debug features should not be present on production builds nor should their
    253 policy.</p>
    254 
    255 <p>The simplest alternative is to only allow the debug feature when SELinux is
    256 disabled on eng/userdebug builds, such as <code>adb root</code> and
    257 <code>adb setenforce 0</code>.</p>
    258 
    259 <p>Another safe alternative is to enclose debug permissions in a
    260 <a href="https://android.googlesource.com/device/lge/hammerhead/+/marshmallow-dev/sepolicy/platform_app.te#3">
    261 userdebug_or_eng</a> statement.</p>
    262 
    263 <h3 id=policy_size_explosion>Policy size explosion</h3>
    264 
    265 
    266 <p><a href="http://arxiv.org/abs/1510.05497">Characterizing SEAndroid Policies in the Wild</a>
    267 describes a concerning trend in the growth of device policy customizations.
    268 Device-specific policy should account for 5&ndash;10% of the overall policy running on
    269 a device. Customizations in the 20%+ range almost certainly contain over
    270 privileged domains and dead policy.</p>
    271 
    272 <p>Unnecessarily large policy:</p>
    273 
    274 <ul>
    275   <li> Takes a double hit on memory as the policy sits in the ramdisk and is also
    276        loaded into kernel memory.
    277   <li> Wastes disk space by necessitating a larger bootimage.
    278   <li> Affects runtime policy lookup times.
    279 </ul>
    280 
    281 <p> The following example shows two devices where the manufacturer-specific policy
    282 comprised 50% and 40% of the on-device policy. A rewrite of the policy yielded
    283 substantial security improvements with no loss in functionality, as shown
    284 below. (AOSP devices Shamu and Flounder are included for comparison.)</p>
    285 
    286 
    287 <p><img alt="Figure 1: Comparison of device-specific policy size after security audit."
    288  src="images/selinux_device_policy_reduction.png" /></p>
    289 <p class="img-caption"><strong>Figure 1</strong>. Comparison of device-specific
    290 policy size after security audit.</p>
    291 
    292 <p>In both cases, the policy was dramatically reduced both in size and in number
    293 of permissions. The decrease in policy size is almost entirely due to removing
    294 unnecessary permissions, many of which were likely  rules generated by
    295 audit2allow that were indiscriminately added to the policy. Dead domains were
    296 also an issue for both devices.</p>
    297 
    298 <h3 id=granting_the_dac_override_capability>Granting the dac_override capability</h3>
    299 
    300 
    301 <p>A<code> dac_override</code> denial means that the offending process is
    302 attempting to access a file with the incorrect unix user/group/world permissions.
    303 The proper solution is almost never to grant the <code>dac_override</code> permission.
    304 Instead <a href="https://android-review.googlesource.com/#/c/174530/5/update_engine.te@11">
    305 change the unix permissions on the file or process</a>. A few domains such as
    306 init, vold, and installd genuinely need the ability to override unix file
    307 permissions to access other processes files. See
    308 <a href="http://danwalsh.livejournal.com/69478.html">Dan Walshs blog</a>
    309 for a more in-depth explanation.</p>
    310 
    311   </body>
    312 </html>
    313