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–95% of the final on-device policy with device-specific 32 customizations making up the remaining 5–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/<vendor>/<target>/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.<target>.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/<oem>/<target>/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/<oem>/<target>/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–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