| <html devsite> |
| <head> |
| <title>Configuring Discretionary Access Control (DAC)</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| {% include "_versions.html" %} |
| <!-- |
| 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> |
| Filesystem objects and services added to the build frequently need separate, |
| unique IDs, known as Android IDs (AIDs). Currently, many resources such as |
| files and services use core (Android-defined) AIDs unnecessarily; in many |
| cases you can use OEM (OEM-defined) AIDs instead. |
| </p> |
| |
| <p> |
| Earlier versions of Android (Android 7.x and lower) extended the AIDs |
| mechanism using a device-specific <code>android_filesystem_config.h</code> |
| file to specify filesystem capabilities and/or custom OEM AIDs. However, this |
| system was unintuitive as it did not support using nice names for OEM AIDs, |
| requiring you to specify the raw numeric for user and group fields without a |
| way to associate a friendly name with the numeric AID. |
| </p> |
| |
| <p> |
| Newer versions of Android (Android 8.0 and higher) support a new method for |
| extending filesystem capabilities, This new method has support for the |
| following: |
| </p> |
| |
| <ul> |
| <li>Multiple source locations for configuration files (enables extensible |
| build configurations).</li> |
| <li>Build-time sanity checking of OEM AID values.</li> |
| <li>Generation of a custom OEM AID header that can be used in source files as |
| needed.</li> |
| <li>Association of a friendly name with the actual OEM AID value. Supports |
| non-numeric string arguments for user and group, i.e. "foo" instead of |
| "2901".</li> |
| </ul> |
| |
| <p> |
| Additional improvements include the removal of the <code>android_ids[]</code> |
| array from |
| <code>system/core/include/private/android_filesystem_config.h</code>. This |
| array now exists in Bionic as a fully private generated array, with |
| accessors via <code>getpwnam()</code> and <code>getgrnam()</code>. (This has |
| the side effect of producing stable binaries as core AIDs are modified.) For |
| tooling and a README file with more details, refer to |
| <code>build/make/tools/fs_config</code>. |
| </p> |
| |
| <aside class="note"> |
| <strong>Note:</strong> While you can still use the <a href="#older">filesystem |
| override method from previous Android releases</a>, you cannot use it |
| simultaneously with the new AIDs mechanism. Using the new mechanism whenever |
| possible is recommended. |
| </aside> |
| |
| <h2 id="adding-android-aids">Adding Android IDs (AIDs)</h2> |
| |
| <p> |
| Android 8.0 removed the <code>android_ids[]</code> array from the Android |
| Open Source Project (AOSP). All AID-friendly names are instead generated from |
| the <code>system/core/include/private/android_filesystem_config.h</code> |
| header file when generating the Bionic <code>android_ids[]</code> array. Any |
| <code>define</code> matching <code>AID_*</code> is picked up by the tooling |
| and <strong>*</strong> becomes the lowercase name. |
| </p> |
| |
| <p> |
| For example, in <code>private/android_filesystem_config.h</code>: |
| </p> |
| |
| <pre class="prettyprint">#define AID_SYSTEM 1000</pre> |
| |
| <p> |
| Becomes: |
| </p> |
| |
| <ul> |
| <li>Friendly name: system</li> |
| <li>uid: 1000</li> |
| <li>gid: 1000</li> |
| </ul> |
| |
| <p> |
| To add a new AOSP core AID, simply add the <code>#define</code> to the |
| <code>android_filesystem_config.h</code> header file. The AID will be |
| generated at build and made available to interfaces that use user and group |
| arguments. The tooling validates the new AID is not within the APP or OEM |
| ranges; it also respects changes to those ranges and should automatically |
| reconfigure on changes or new OEM-reserved ranges. |
| </p> |
| |
| <h2 id="configuring-aids">Configuring AIDs</h2> |
| |
| <p> |
| To enable the new AIDs mechanism, set <code>TARGET_FS_CONFIG_GEN</code> in the |
| <code>BoardConfig.mk</code> file. This variable holds a list of configuration |
| files, enabling you to append files as needed. |
| </p> |
| |
| <aside class="caution"> |
| <strong>Caution:</strong> Don't use <code>TARGET_FS_CONFIG_GEN</code> with the |
| older <code>TARGET_ANDROID_FILESYSTEM_CONFIG_H</code> method from older |
| Android releases! You will get an error. |
| </aside> |
| |
| <p> |
| By convention, configuration files use the name <code>config.fs</code>, but in |
| practice you can use any name. <code>config.fs</code> files are in the |
| <a href="https://docs.python.org/2/library/configparser.html" class="external">Python |
| ConfigParser ini format</a> and include a caps section (for configuring file |
| system capabilities) and an AIDs section (for configuring OEM AIDs). |
| </p> |
| |
| <h3 id="configuring-the-caps-section">Configuring the caps section</h3> |
| |
| <aside class="note"> |
| <strong>Note:</strong> <a href="/devices/tech/config/ambient">Ambient |
| capabilities</a> are the preferred mechanism for setting capabilities for |
| services launched by <code>init</code> (this method keeps all aspects for the |
| service configuration in a single <code>.rc</code> file). We recommend using |
| ambient capabilities for these services instead of configuring file system |
| capabilities using the caps section in <code>config.fs</code> files. When |
| setting capabilities for services <strong>not launched by |
| <code>init</code></strong>, continue to configure file system capabilities |
| using <code>fs_config.c</code>. |
| </aside> |
| |
| <p> |
| The caps section supports setting |
| <a href="http://man7.org/linux/man-pages/man7/capabilities.7.html" class="external">file |
| system capabilities</a> on filesystem objects within the build (the filesystem |
| itself must also support this functionality). |
| </p> |
| |
| <p> |
| Because running a stable service as root in Android causes a |
| <a href="/compatibility/cts/index.html">Compatibility Test Suite (CTS)</a> |
| failure, previous requirements for retaining a capability while running a |
| process or service involved setting up capabilities then using |
| <code>setuid</code>/<code>setgid</code> to a proper AID to run. With caps, you |
| can skip these requirements and have the kernel do it for you. When control is |
| handed to <code>main()</code>, your process already has the capabilities it |
| needs so your service can use a non-root user and group (this is the preferred |
| way for starting privileged services). |
| </p> |
| |
| <p> |
| The caps section uses the following syntax: |
| </p> |
| |
| <table> |
| <tr> |
| <th>Section</th> |
| <th>Value</th> |
| <th>Definition</th> |
| </tr> |
| <tr> |
| <td><code>[path]</code></td> |
| <td></td> |
| <td>The filesystem path to configure. A path ending in / is considered a dir, |
| else it's a file. |
| <br><br>It is an error to specify multiple sections with the same |
| <code>[path]</code> in different files. In Python versions <= 3.2, the |
| same file may contain sections that override the previous section; in Python |
| 3.2, it's set to strict mode.</td> |
| </tr> |
| <tr> |
| <td><code>mode</code></td> |
| <td>Octal file mode</td> |
| <td>A valid octal file mode of at least 3 digits. If 3 is specified, it is |
| prefixed with a 0, else mode is used as is.</td> |
| </tr> |
| <tr> |
| <td><code>user</code></td> |
| <td>AID_<user></td> |
| <td>Either the C <code>define</code> for a valid AID or the friendly name |
| (e.g. both <code>AID_RADIO</code> and <code>radio</code> are acceptable). To |
| define a custom AID, see <a href="#configuring-the-aid-section">Configuring |
| the AID section</a>.</td> |
| </tr> |
| <tr> |
| <td><code>group</code></td> |
| <td>AID_<group></td> |
| <td>Same as user.</td> |
| </tr> |
| <tr> |
| <td><code>caps</code></td> |
| <td>cap*</td> |
| <td>The name as declared in |
| <code>system/core/include/private/android_filesystem_capability.h</code> |
| without the leading <code>CAP_</code>. Mixed case allowed. Caps can also be |
| the raw: |
| <ul> |
| <li>binary (0b0101)</li> |
| <li>octal (0455)</li> |
| <li>int (42)</li> |
| <li>hex (0xFF)</li> |
| </ul> |
| Separate multiple caps using whitespaces.</td> |
| </tr> |
| </table> |
| |
| <p> |
| For a usage example, see <a href="#using-file-system-capabilities">Using file |
| system capabilities</a>. |
| </p> |
| |
| <h3 id="configuring-the-aid-section">Configuring the AID section</h3> |
| |
| <p> |
| The AID section contains OEM AIDs and uses the following syntax: |
| </p> |
| |
| <table> |
| <tr> |
| <th>Section</th> |
| <th>Value</th> |
| <th>Definition</th> |
| </tr> |
| <tr> |
| <td><code>[AID_<name>]</code></td> |
| <td></td> |
| <td>The <code><name></code> can contain characters in the set |
| uppercase, numbers, and underscores. The lowercase version is used as the |
| friendly name. The generated header file for code inclusion uses the exact |
| <code>AID_<name></code>. |
| <br><br>It is an error to specify multiple sections with the same |
| <code>AID_<name></code> (case insensitive with the same constraints as |
| <code>[path]</code>).</td> |
| </tr> |
| <tr> |
| <td><code>value</code></td> |
| <td><number></td> |
| <td>A valid C style number string (hex, octal, binary and decimal). |
| <br><br>It is an error to specify multiple sections with the same value option |
| <strong>or</strong> to specify a value that is outside of the inclusive OEM |
| ranges (defined in |
| <code>system/core/include/private/android_filesystem_config.h</code>): |
| <ul> |
| <li>AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)</li> |
| <li>AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)</li> |
| </ul> |
| </td> |
| </tr> |
| </table> |
| |
| <p> |
| For usage examples, see <a href="#defining-oem-aid-name">Defining an OEM |
| AID</a> and <a href="#using-oem-aids">Using an OEM AID</a>. |
| </p> |
| |
| <h2 id="usage-examples">Usage examples</h2> |
| |
| <p> |
| The following examples detail how to define and use an OEM AID and how to |
| enable filesystem capabilities. OEM AID names |
| (<strong>[AID_</strong><em>name<strong></em>]</strong>) must begin with the |
| value "<strong>vendor_</strong>" to ensure they do not conflict with future |
| AOSP names. |
| </p> |
| |
| <h3 id="defining-oem-aid-name">Defining OEM AID names</h2> |
| |
| <p> |
| To define an OEM AID, create a <code>config.fs</code> file and set |
| the AID value. For example, in <code>device/x/y/config.fs</code>, set the |
| following: |
| </p> |
| |
| <pre> |
| [AID_VENDOR_FOO] |
| value: 2900 |
| </pre> |
| |
| <p> |
| After creating the file, set the <code>TARGET_FS_CONFIG_GEN</code> variable |
| and point to it in <code>BoardConfig.mk</code>. For example, in |
| <code>device/x/y/BoardConfig.mk</code>, set the following: |
| </p> |
| |
| <pre class="prettyprint">TARGET_FS_CONFIG_GEN += device/x/y/config.fs</pre> |
| |
| <p> |
| Your custom AID can now be consumed by the system at large on a new build. |
| </p> |
| |
| <h2 id="using-oem-aids">Using OEM AIDs</h2> |
| |
| <p> |
| To use an OEM AID, in your C code, add <code>#include |
| "generated_oem_aid.h"</code> and start using the declared identifiers. For |
| example, in <code>my_file.c</code>, add the following: |
| </p> |
| |
| <pre> |
| #include "generated_oem_aid.h" |
| … |
| |
| If (ipc->uid == AID_VENDOR_FOO) { |
| // Do something |
| ... |
| </pre> |
| |
| <h3 id="using-friendly-names">Using friendly names</h3> |
| |
| <p> |
| In Android {{ androidPVersionNumber }}, you can use the friendly name for any |
| interface that supports AID names. For example: |
| </p> |
| |
| <ul> |
| <li>In a <code>chown</code> command in <code>some/init.rc</code>: |
| <pre> |
| chown vendor_foo /vendor/some/vendor_foo/file |
| </pre> |
| </li> |
| <li>In a <code>service</code> in <code>some/init.rc</code>: |
| |
| <pre> |
| service vendor_foo /vendor/bin/foo_service |
| user vendor_foo |
| group vendor_foo |
| </pre> |
| </li> |
| </ul> |
| |
| <p> |
| Because the internal mapping from friendly name to uid is performed by |
| <code>/vendor/etc/passwd</code> and <code>/vendor/etc/group</code>, the vendor |
| partition must be mounted. |
| </p> |
| |
| <h2 id="associating-friendly-names">Associating friendly names</h2> |
| |
| <p> |
| Android {{ androidPVersionNumber }} includes support for associating a |
| friendly name with the actual OEM AID value. You can use non-numeric string |
| arguments for user and group, i.e. "<strong>vendor_</strong>foo" instead of |
| "2901". |
| </p> |
| |
| <h2 id="converting-aid-to-friendly">Converting from AID to friendly names</h2> |
| |
| <p> |
| For |
| <a href="#using-oem-aid">OEM AIDs</a>, Android 8.x required the use of |
| <code>oem_####</code> with <code>getpwnam</code> and similar functions, as |
| well in places that handle lookups via <code>getpwnam</code> (such as |
| <code>init</code> scripts). In Android {{ androidPVersionNumber }}, you can |
| use the <code>getpwnam</code> and <code>getgrnam</code> friends in Bionic for |
| converting from Android IDs (AIDs) to friendly names and vice versa. |
| </p> |
| |
| <h3 id="using-file-system-capabilities">Using file system capabilities</h3> |
| |
| <p> |
| To enable filesystem capabilities, create a caps section in the |
| <code>config.fs</code> file. For example, in |
| <code>device/x/y/config.fs</code>, add the following section: |
| </p> |
| |
| <pre> |
| [system/bin/foo_service] |
| mode: 0555 |
| user: AID_VENDOR_FOO |
| group: AID_SYSTEM |
| caps: SYS_ADMIN | SYS_NICE |
| </pre> |
| |
| <aside class="note"> |
| <strong>Note:</strong> The nice names <code><strong>vendor_</strong>foo</code> |
| and <code>system</code> could be used here as well. |
| </aside> |
| |
| <p> |
| After creating the file, set the <code>TARGET_FS_CONFIG_GEN</code> to point to |
| that file in <code>BoardConfig.mk</code>. For example, in |
| <code>device/x/y/BoardConfig.mk</code>, set the following: |
| </p> |
| |
| <pre> |
| TARGET_FS_CONFIG_GEN += device/x/y/config.fs |
| </pre> |
| |
| <p> |
| When service <code><strong>vendor_</strong>foo</code> is executed, it starts |
| with capabilities <code>CAP_SYS_ADMIN</code> and <code>CAP_SYS_NICE</code> |
| without <code>setuid</code> and <code>setgid</code> calls. In addition, the |
| <code><strong>vendor_</strong>foo</code> service's SELinux policy no longer |
| needs capability <code>setuid</code> and <code>setgid</code> and can be |
| deleted. |
| </p> |
| |
| <h2 id="older">Configuring overrides (Android 6.x-7.x)</h2> |
| |
| <p> |
| Android 6.0 relocated <code>fs_config</code> and associated structure |
| definitions |
| (<code>system/core/include/private/android_filesystem_config.h</code>) to |
| <code>system/core/libcutils/fs_config.c</code> where they could be updated or |
| overridden by binary files installed in |
| <code>/system/etc/fs_config_dirs</code> and |
| <code>/system/etc/fs_config_files</code>. Using separate matching and parsing |
| rules for directories and files (which could use additional glob expressions) |
| enabled Android to handle directories and files in two different tables. |
| Structure definitions in <code>system/core/libcutils/fs_config.c</code> not |
| only allowed runtime reading of directories and files, but the host could use |
| the same files during build time to construct filesystem images as |
| <code>${OUT}/system/etc/fs_config_dirs</code> and |
| <code>${OUT}/system/etc/fs_config_files</code>. |
| </p> |
| |
| <p> |
| While the override method of extending the filesystem has been superseded by |
| the modular config system introduced in Android 8.0, you can still use the old |
| method if desired. The following sections detail how to generate and include |
| override files and configure the filesystem. |
| </p> |
| |
| <h3 id=older-generate>Generating override files</h3> |
| |
| <p>You can generate the aligned binary files |
| <code>/system/etc/fs_config_dirs</code> and |
| <code>/system/etc/fs_config_files</code> using the |
| <code>fs_config_generate</code> tool in <code>build/tools/fs_config</code>. The |
| tool uses a <code>libcutils</code> library function |
| (<code>fs_config_generate()</code>) to manage DAC requirements into a buffer |
| and defines rules for an include file to institutionalize the DAC rules.</p> |
| |
| <p>To use, create an include file in |
| <code>device/<em>vendor</em>/<em>device</em>/android_filesystem_config.h</code> |
| that acts as the override. The file must use the |
| <code>structure fs_path_config</code> format defined in |
| <code>system/core/include/private/android_filesystem_config.h</code> with the |
| following structure initializations for directory and file symbols:</p> |
| <ul> |
| <li>For directories, use <code>android<strong>_device</strong>_dirs[]</code>.</li> |
| <li>For files, use <code>android<strong>_device</strong>_files[]</code>.</li> |
| </ul> |
| |
| <p> |
| When not using <code>android_device_dirs[]</code> and |
| <code>android_device_files[]</code>, you can define |
| <code>NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS</code> and |
| <code>NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES</code> (see the |
| <a href="#older-example">example</a> below). You can also specify the override |
| file using <code>TARGET_ANDROID_FILESYSTEM_CONFIG_H</code> in the board |
| configuration, with an enforced basename of |
| <code>android_filesystem_config.h</code>. |
| </p> |
| |
| <h3 id=older-include>Including override files</h3> |
| |
| <p> |
| To include files, ensure that <code>PRODUCT_PACKAGES</code> includes |
| <code>fs_config_dirs</code> and/or <code>fs_config_files</code> so it can |
| install them to <code>/system/etc/fs_config_dirs</code> and |
| <code>/system/etc/fs_config_files</code>, respectively. The build system |
| searches for custom <code>android_filesystem_config.h</code> in |
| <code>$(TARGET_DEVICE_DIR)</code>, where <code>BoardConfig.mk</code> exists. |
| If this file exists elsewhere, set board config variable |
| <code>TARGET_ANDROID_FILESYSTEM_CONFIG_H</code> to point to that location. |
| </p> |
| |
| <h3 id=older-configure>Configuring the filesystem</h3> |
| |
| <p> |
| To configure the filesystem in Android 6.0 and higher: |
| </p> |
| |
| <ol> |
| <li>Create the <code>$(TARGET_DEVICE_DIR)/android_filesystem_config.h</code> |
| file.</li> |
| <li>Add the <code>fs_config_dirs</code> and/or <code>fs_config_files</code> to |
| <code>PRODUCT_PACKAGES </code>in the board configuration file (e.g., |
| <code>$(TARGET_DEVICE_DIR)/device.mk</code>).</li> |
| </ol> |
| |
| <h3 id=older-example>Override example</h3> |
| |
| <p> |
| This example shows a patch for overriding the <code>system/bin/glgps</code> |
| daemon to add wake lock support in the |
| <code>device/<em>vendor</em>/<em>device</em></code> directory. Keep the |
| following in mind: |
| </p> |
| |
| <ul> |
| <li>Each structure entry is the mode, uid, gid, capabilities, and the name. |
| <code>system/core/include/private/android_filesystem_config.h</code> is |
| included automatically to provide the manifest #defines |
| (<code>AID_ROOT</code>, <code>AID_SHELL</code>, |
| <code>CAP_BLOCK_SUSPEND</code>).</li> |
| <li>The <code>android_device_files[]</code> section includes an action to |
| suppress access to <code>system/etc/fs_config_dirs</code> when unspecified, |
| which serves as an additional DAC protection for lack of content for directory |
| overrides. However, this is weak protection; if someone has control over |
| <code>/system</code>, they can typically do anything they want.</li> |
| </ul> |
| |
| <pre class="devsite-click-to-copy"> |
| diff --git a/android_filesystem_config.h b/android_filesystem_config.h |
| new file mode 100644 |
| index 0000000..874195f |
| --- /dev/null |
| +++ b/android_filesystem_config.h |
| @@ -0,0 +1,36 @@ |
| +/* |
| + * Copyright (C) 2015 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. |
| + */ |
| + |
| +/* This file is used to define the properties of the filesystem |
| +** images generated by build tools (eg: mkbootfs) and |
| +** by the device side of adb. |
| +*/ |
| + |
| +#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS |
| +/* static const struct fs_path_config android_device_dirs[] = { }; */ |
| + |
| +/* Rules for files. |
| +** These rules are applied based on "first match", so they |
| +** should start with the most specific path and work their |
| +** way up to the root. Prefixes ending in * denotes wildcard |
| +** and will allow partial matches. |
| +*/ |
| +static const struct fs_path_config android_device_files[] = { |
| + { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND), |
| "system/bin/glgps" }, |
| +#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS |
| + { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" }, |
| +#endif |
| +}; |
| |
| |
| diff --git a/device.mk b/device.mk |
| index 0c71d21..235c1a7 100644 |
| --- a/device.mk |
| +++ b/device.mk |
| @@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \ |
| libwpa_client \ |
| hostapd \ |
| wpa_supplicant \ |
| - wpa_supplicant.conf |
| + wpa_supplicant.conf \ |
| + fs_config_files |
| |
| ifeq ($(TARGET_PREBUILT_KERNEL),) |
| ifeq ($(USE_SVELTE_KERNEL), true) |
| </pre> |
| |
| <h3 id=older-migration>Migrating filesystems from earlier releases</h3> |
| |
| <p> |
| When migrating filesystems from Android 5.x and earlier, keep in mind that |
| Android 6.x: |
| </p> |
| |
| <ul> |
| <li>Removes some includes, structures, and inline definitions.</li> |
| <li>Requires a reference to <code>libcutils</code> instead of running directly |
| from <code>system/core/include/private/android_filesystem_config.h</code>. |
| Device manufacturer private executables that depend on |
| <code>system/code/include/private_filesystem_config.h</code> for the file or |
| directory structures or <code>fs_config</code> must add <code>libcutils</code> |
| library dependencies.</li> |
| <li>Requires device manufacturer private branch copies of the |
| <code>system/core/include/private/android_filesystem_config.h</code> with |
| extra content on existing targets to move to |
| <code>device/<em>vendor</em>/<em>device</em>/android_filesystem_config.h</code>. |
| </li> |
| <li>Reserves the right to apply SELinux Mandatory Access Controls (MAC) to |
| configuration files on the target system, implementations that include custom |
| target executables using <code>fs_config()</code> must ensure access.</li> |
| </ul> |
| |
| </body> |
| </html> |