Difference between revisions of "NB SEforAndroid 2"
(→Allow-all Entry) |
|||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= Policy File Configuration Details = | = Policy File Configuration Details = | ||
− | This section details the specific SE for Android policy configuration files (i.e. those not used by 'standard' Linux based SELinux) | + | This section details the specific SE for Android policy configuration files (i.e. those not used by 'standard' Linux based SELinux). Where those files are used to compute contexts using the SE for Android <tt>libselinux</tt> functions, those functions are also described with examples. |
As this project is continually being enhanced, it is recommended that the official project wiki is checked for the latest enhancements at [[SEforAndroid | SEforAndroid]] | As this project is continually being enhanced, it is recommended that the official project wiki is checked for the latest enhancements at [[SEforAndroid | SEforAndroid]] | ||
− | == SELinux MAC Files == | + | == SELinux MAC Configuration Files == |
=== seapp_contexts File === | === seapp_contexts File === | ||
This file is loaded and sorted into memory automatically on first use of one of the following SE for Android libselinux functions that are called by the SE for Android enabled services: | This file is loaded and sorted into memory automatically on first use of one of the following SE for Android libselinux functions that are called by the SE for Android enabled services: | ||
Line 378: | Line 378: | ||
</pre> | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | + | == Install MMAC Configuration File == | |
+ | The <tt>mac_permissions.xml</tt> file is used to configure Install MMAC policy and provides two main functions: | ||
+ | # x.509 certificate to <tt>seinfo</tt> string mapping so that Zygote spawns the application in the correct domain. See the [[#Computing a Process Context | Computing a Process Context]] section for how this is achieved using information also contained in the <tt>seapp_contexts</tt> file (AOSP and SEAndroid). | ||
+ | # Install MMAC permission checking (SEAndroid only). | ||
+ | It is important to note that all third party apps will be subject to the <tt><nowiki><default></nowiki></tt> install MMAC policy defined in this file. This is a requirement of AOSP in that all third party apps must be treated alike (i.e. distinctions can only be made between system apps and third party apps and among the system apps, not between two different third party apps). | ||
+ | |||
+ | An example AOSP <tt>mac_permissions.xml</tt> file that also shows the <tt><nowiki><default></nowiki></tt> entry is: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <policy> | ||
+ | <!-- Platform dev key in AOSP --> | ||
+ | <signer signature="@PLATFORM" > | ||
+ | <seinfo value="platform" /> | ||
+ | </signer> | ||
+ | |||
+ | <!-- Media dev key in AOSP --> | ||
+ | <signer signature="@MEDIA" > | ||
+ | <seinfo value="media" /> | ||
+ | </signer> | ||
+ | |||
+ | <!-- shared dev key in AOSP --> | ||
+ | <signer signature="@SHARED" > | ||
+ | <seinfo value="shared" /> | ||
+ | </signer> | ||
+ | |||
+ | <!-- release dev key in AOSP --> | ||
+ | <signer signature="@RELEASE" > | ||
+ | <seinfo value="release" /> | ||
+ | </signer> | ||
+ | |||
+ | <!-- All other keys --> | ||
+ | <default> | ||
+ | <seinfo value="default" /> | ||
+ | </default> | ||
+ | </policy> | ||
+ | </pre> | ||
+ | |||
+ | An example SEAndroid <tt><nowiki><default></nowiki></tt> package policy is: | ||
<pre> | <pre> | ||
<!-- All other keys --> | <!-- All other keys --> | ||
Line 402: | Line 435: | ||
==== Signature Entries ==== | ==== Signature Entries ==== | ||
− | The <tt><nowiki><signer signature=</nowiki></tt> entry may have the public base16 signing key present in the string or it may have an entry starting with <tt>@</tt> | + | The <tt><nowiki><signer signature=</nowiki></tt> entry may have the public base16 signing key present in the string or it may have an entry starting with <tt>@</tt> then a keyword (e.g <tt>@PLATFORM</tt>) that will signify that the key is to be extracted from a pem file as discussed in the <tt>[[#insertkeys.py | insertkeys.py]]</tt> section: |
<pre> | <pre> | ||
<!-- Platform dev key in AOSP --> | <!-- Platform dev key in AOSP --> | ||
Line 411: | Line 444: | ||
</pre> | </pre> | ||
− | If a base16 key is required, it can be extracted from a package using the <tt>setool</tt> utility as described in the [[#setool | setool]] section. | + | If a base16 key is required, it can be extracted from a package using the <tt>setool</tt> utility as described in the <tt>[[#setool | setool]]</tt> section. |
==== Policy Rules ==== | ==== Policy Rules ==== | ||
− | The following rules have been extracted from the | + | The following rules have been extracted from the SEAndroid <tt>mac_permissions.xml</tt> file: |
* A signature is a hex encoded X.509 certificate and is required for each signer tag. | * A signature is a hex encoded X.509 certificate and is required for each signer tag. | ||
Line 444: | Line 477: | ||
** If none of the cases apply then the app is denied. | ** If none of the cases apply then the app is denied. | ||
− | An edited form of | + | An edited form of an SEAndroid <tt>mac_permissions.xml</tt> file is as follows: |
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
Line 501: | Line 534: | ||
− | == Intent | + | == Intent MMAC Configuration Files == |
− | There are two configuration files to support | + | There are two configuration files to support Intent MMAC, they are: |
− | :: <tt>intent_mac.xml</tt> - This defines the intents that will be allowed between each source and destination. The source and destination may be package names or <tt><nowiki><type | + | :: <tt>intent_mac.xml</tt> - This defines the intents that will be allowed between each source and destination. The source and destination may be package names or <tt><nowiki><type name</nowiki></tt> entries defined in the <tt>mmac_types.xml</tt> file (see [[Using Type or Package Names | Using Type or Package Names]] below on implementing these). There is also an optional <tt><nowiki><allow-all></nowiki></tt> section. |
− | :: <tt>mmac_types.xml</tt> - Contains <tt><nowiki><type | + | :: <tt>mmac_types.xml</tt> - Contains <tt><nowiki><type name</nowiki></tt> entries allowing source and destination entries defined in the <tt>intent_mac.xml</tt> file to manage intents on a package, signature and/or permissions basis. |
=== intent_mac.xml File === | === intent_mac.xml File === | ||
− | The file supports two | + | The file supports two optional types of entry: |
− | # | + | # <tt><nowiki><intent></nowiki></tt> filters that specify actions (intents) allowed between their source and destination, additional optional entries may also be added that refine the intent. The source and destination entries may be defined in the <tt>[[#mmac_types.xml File|mmac_types.xml]]</tt> file. |
− | # | + | # <tt><nowiki><allow-all></nowiki></tt> that will allow all intents from the source to destination entries. |
− | |||
− | + | All <tt>intent_mac.xml</tt> file entries are between <tt><nowiki><policy></nowiki></tt> tags: | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
− | <policy> | + | <policy> |
+ | ...... | ||
+ | </policy> | ||
+ | </pre> | ||
− | + | The build process supports additional device specific <tt>intent_mac.xml</tt> files as described in the [[NB_SEforAndrooid_1#Building the Policy|Building the Policy]] section. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ==== Intent Filter Entry ==== | |
− | + | Each intent entry is as follows: | |
− | An | + | * <tt><nowiki><intent></nowiki></tt> start tag. |
+ | ** <tt><nowiki><filter></nowiki></tt> start tag. The entries that follow would generally be obtained from the appropriate package manifest that describe the intent and its parameters. | ||
+ | *** An <tt><nowiki><action name="" /></nowiki></tt> entry defining the intent action name. | ||
+ | *** Zero or more <tt><nowiki><category name="" /></nowiki></tt> entries defining the intent category name. | ||
+ | *** Zero or more <tt><nowiki><data scheme="" /></nowiki></tt> entries defining the intent scheme data specification. | ||
+ | *** Zero or more <tt><nowiki><data mimeType="" /></nowiki></tt> entries defining the intent mime type data specification. | ||
+ | ** <tt><nowiki></filter></nowiki></tt> end tag. | ||
+ | ** One or more <tt><nowiki><allow</nowiki></tt> entries that consist of the following: | ||
+ | *** An optional rule <tt>name=</tt> entry that will be displayed in debug logs. | ||
+ | *** Optional <tt>src=</tt> and <tt>dst=</tt> references for the allowed intents. These entries are generally <tt><nowiki><type name=""</nowiki></tt> entries defined in the <tt>mmac_types.xml</tt> file, however they may also be package names, see the [[Using Type or Package Names | Using Type or Package Names]] section for further details. Note: It is recommended that both <tt>src=</tt> and <tt>dst=</tt> entries are specified. Not specifying either of them or the <tt>dst=</tt> will allow the intent to 'anywhere'. The only exception should be when source context matching is used. | ||
+ | *** An optional <tt>srcctx=</tt> entry that will be matched against the source app process context. | ||
+ | ** <tt>/></tt> The <tt>allow</tt> end tag. | ||
+ | * <tt><nowiki></intent></nowiki></tt> end tag. | ||
+ | |||
+ | Example entries are: | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
− | |||
<policy> | <policy> | ||
<intent> | <intent> | ||
<filter> | <filter> | ||
− | <action name="android. | + | <action name="android.intent.action.CALL_PRIVILEGED"/> |
+ | <data scheme="tel"/> | ||
+ | <data scheme="voicemail"/> | ||
</filter> | </filter> | ||
− | <allow src=" | + | <allow src="contacts_app" dst="telephony_app"/> |
− | < | + | </intent> |
− | <allow src=" | + | |
+ | <intent> | ||
+ | <filter> | ||
+ | <action name="android.intent.action.VIEW"/> | ||
+ | <data mimeType="vnd.android.cursor.dir/calls" /> | ||
+ | </filter> | ||
+ | <allow src="telephony_app" dst="contacts_app"/> | ||
</intent> | </intent> | ||
</policy> | </policy> | ||
</pre> | </pre> | ||
− | ==== | + | ==== allow-all Entry ==== |
− | + | An <tt><nowiki><allow-all></nowiki></tt> entry consists of: | |
− | * | + | * <tt><nowiki><allow-all></nowiki></tt> start tag. |
− | * | + | ** Zero of more <tt><nowiki><allow</nowiki></tt> entries that consist of the following: |
− | < | + | *** An optional rule <tt>name=</tt> entry that will be displayed in debug logs. |
− | < | + | *** Optional <tt>src</tt> and <tt>dst</tt> references of the allowed intents. These entries are generally package names to allow all intents to flow between them, however they may be <tt><nowiki><type name=""</nowiki></tt> entries defined in the <tt>mmac_types.xml</tt> file, see the [[Using Type or Package Names | Using Type or Package Names]] section for further details. |
− | < | + | *** An optional <tt>srcctx</tt> entry that will be matched against the source app process context. |
+ | ** <tt>/></tt> The <tt>allow</tt> end tag. | ||
+ | * <tt><nowiki></allow-all></nowiki></tt> end tag. | ||
− | + | An example <tt><nowiki><allow-all></nowiki></tt> entry: | |
− | + | <pre> | |
− | + | <allow-all> | |
− | + | <allow name="phone_to_sms" src="com.android.phone" dst="com.android.smspush"/> | |
− | + | <allow name="shell" srcctx="u:r:shell:s0"/> | |
− | + | <allow name="su" srcctx="u:r:su:s0"/> | |
− | + | </allow-all> | |
− | + | ||
− | + | ||
</pre> | </pre> | ||
− | + | ===Using Type or Package Names=== | |
+ | The above <tt><nowiki><allow name=</nowiki></tt> example <tt>src=</tt> and <tt>dst=</tt> entries shown are the actual package names. These entries may be implemented in the following ways: | ||
+ | |||
+ | 1) Generate a new type entry for each package name in the <tt>mmac_types.xml</tt> file, for example: | ||
<pre> | <pre> | ||
− | < | + | <type name="com.android.phone"/> |
− | < | + | <type name="com.android.smspush"/> |
+ | </pre> | ||
− | + | : This would satisfy the <tt><nowiki><allow name="phone_to_sms"</nowiki></tt> example entry given above. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | </ | + | 2) Use existing type entries that already define the package name, for example the default <tt>mmac_types.xml</tt> file has the following entries: |
+ | <pre> | ||
+ | <type name="wappush_app"> | ||
+ | <signature value="@RELEASE"/> | ||
+ | <package value="com.android.smspush"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="telephony_app"> | ||
+ | <signature value="@PLATFORM"/> | ||
+ | <package value="com.android.phone"/> | ||
+ | </type> | ||
</pre> | </pre> | ||
− | + | : The example <tt><nowiki><allow</nowiki></tt> entry would then be defined as: | |
− | + | ||
− | + | ||
<pre> | <pre> | ||
− | < | + | <allow name="phone_to_sms" src="telephony_app" dst="wappush_app"/> |
− | + | ||
</pre> | </pre> | ||
− | + | 3) Set the <tt>persist.mac_applyNameTypes</tt> permission to <tt>true</tt>, as this enables package names to be automatically be added as <tt><nowiki><type name=</nowiki></tt> entries as the policy is loaded. | |
<pre> | <pre> | ||
adb shell su 0 setprop persist.mac_applyNameTypes 1 | adb shell su 0 setprop persist.mac_applyNameTypes 1 | ||
</pre> | </pre> | ||
− | |||
− | |||
− | + | === mmac_types.xml File === | |
− | + | The <tt>mmac_types.xml</tt> file contains the <tt><nowiki><type></nowiki></tt> entries that provide the source / destination references for the package and/or permissions rules used by the <tt>intent_mac.xml</tt> file. All entries are between <tt><nowiki><policy></nowiki></tt> tags: | |
− | + | ||
− | + | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
− | < | + | <policy> |
+ | ...... | ||
+ | </policy> | ||
+ | </pre> | ||
− | + | The build process supports additional device specific <tt>mmac_types.xml</tt> files as described in the [[NB_SEforAndroid_1#Building the Policy|Building the Policy]] section. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | </ | + | Each <tt>mmac_types.xml</tt> file entry is as follows: |
− | </ | + | |
+ | * <tt><nowiki><type name="" ></nowiki></tt> entry that defines the name that will be referenced by the <tt>intent_mac.xml</tt> file <tt>src=""</tt> and <tt>dst=""</tt> entries. | ||
+ | ** Zero or more <tt>package value=""</tt> entries containing package names. | ||
+ | ** Zero or more <tt><nowiki><signature value="" /></nowiki></tt> entries. These may be the key as extracted by <tt>setool</tt> (but it will need to be copied here from the <tt>[[#setool|setool]]</tt> output), or the <tt>"@.."</tt> format as shown in the example below, the signature will then be automatically generated as part of the build process by <tt>[[#insertkeys.py|insertkeys.py]}</tt> as described in [[NB_SEforAndroid_1#Building the Policy| Building the Policy]] section. It is recommended that a signature is always present. | ||
+ | ** Zero or more <tt>permission value="" /></tt> entries containing the allowed package permissions. | ||
+ | * <tt><nowiki></type></nowiki></tt> end tag. | ||
Example entries are: | Example entries are: | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
− | < | + | <policy> |
− | + | ||
<type name="telephony_app"> | <type name="telephony_app"> | ||
<signature value="@PLATFORM"/> | <signature value="@PLATFORM"/> | ||
Line 636: | Line 682: | ||
<permission value="android.permission.RECORD_AUDIO"/> | <permission value="android.permission.RECORD_AUDIO"/> | ||
</type> | </type> | ||
+ | </policy> | ||
+ | </pre> | ||
− | </types> | + | |
+ | == Content Provider MMAC Configuration File == | ||
+ | The <tt>content_provider.xml</tt> file supports the following types of entry: | ||
+ | |||
+ | # Package <tt><nowiki><type></nowiki></tt> entries that describe source package parameters. | ||
+ | # Content <tt><nowiki><type></nowiki></tt> entries that describe target content provider parameters. | ||
+ | # <tt><nowiki><attribute></nowiki></tt> entries that assign a common name to multiple <tt><nowiki><type></nowiki></tt> entries. | ||
+ | # <tt><nowiki><allow-content></nowiki></tt> entries that define the source, target and permissions to allow access to content. | ||
+ | |||
+ | All entries are between <tt><nowiki><policy></nowiki></tt> tags: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <policy> | ||
+ | ...... | ||
+ | </policy> | ||
</pre> | </pre> | ||
− | == | + | The build process supports additional device specific <tt>content_provider.xml</tt> files as described in the [[NB_SEforAndroid_1#Building the Policy| Building the Policy]] section. |
− | + | ||
+ | === Package <type> Entries === | ||
+ | Each <tt>content_provider.xml</tt> file package type entry is as follows: | ||
+ | |||
+ | * <tt><nowiki><type name="" component="package" ></nowiki></tt> entry. The <tt>name</tt> entry defines the name that will be referenced by the attribute <tt><nowiki><type></nowiki></tt> and/or <tt><nowiki><allow></nowiki></tt> source entry. The <tt>component</tt> entry specifies this as a package entry (other entries may be supported later). | ||
+ | ** Zero or more <tt><nowiki><package value="" /></nowiki></tt> entries defining the package name. | ||
+ | ** Zero or more <tt><nowiki><signature value="" /></nowiki></tt> entries. These may be the key as extracted by <tt>setool</tt> (but it will need to be copied here from the <tt>[[#setool|setool]]</tt> output), or the <tt>"@.."</tt> format as shown in the example below, the signature will then be automatically generated as part of the build process by <tt>[[#insertkeys.py|insertkeys.py]]</tt> as described in [[NB_SEforAndroid_1#Building the Policy| Building the Policy]] section. | ||
+ | ** Zero or more <tt><nowiki><permission value="" /></nowiki></tt> entries defining the permissions. | ||
+ | * <tt><nowiki></type></nowiki></tt> end tag. | ||
+ | |||
+ | When computing access to content the following precedence rules apply to package type entries: | ||
+ | |||
+ | # Signature defined over signature not defined. | ||
+ | # Package name defined over package name not defined. | ||
+ | # Permission set defined over permission set not defined. | ||
+ | |||
+ | There is no distinction between a stanza that has more signatures than another. They are considered of equal precedence. | ||
+ | |||
+ | Example entries are: | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
− | < | + | <policy> |
+ | <type name="platform" component="package"> | ||
+ | <signature value="@PLATFORM"/> | ||
+ | </type> | ||
− | < | + | <type name="shared" component="package"> |
− | + | <signature value="@SHARED"/> | |
− | </ | + | </type> |
− | + | <type name="release" component="package"> | |
+ | <signature value="@RELEASE"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="media" component="package"> | ||
+ | signature value="@MEDIA"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="defualt_package" component="package"> | ||
+ | </type> | ||
+ | |||
+ | <type name="demo_resolver_package" component="package"> | ||
+ | <package value="com.example.resolvecontent" /> | ||
+ | <permission value="com.se4android.contentprovider.READ" /> | ||
+ | <permission value="com.se4android.contentprovider.WRITE" /> | ||
+ | </type> | ||
+ | </policy> | ||
</pre> | </pre> | ||
+ | |||
+ | === Provider <type> Entries === | ||
+ | Each <tt>content_provider.xml</tt> file provider type entry is as follows: | ||
+ | |||
+ | * <tt><nowiki><type name="" ></nowiki></tt> entry. The <tt>name</tt> entry defines the name that will be referenced by the attribute <tt><nowiki><type></nowiki></tt> and/or <tt><nowiki><allow></nowiki></tt> destination entries. | ||
+ | ** Zero or more <tt><nowiki><provider value="" /></nowiki></tt> entries defining the provider authority. | ||
+ | ** Zero or more <tt><nowiki><package value="" /></nowiki></tt> entries defining the package name. | ||
+ | ** Zero or more <tt><nowiki><signature value="" /></nowiki></tt> entries. These may be the key as extracted by <tt>setool</tt> (but it will need to be copied here from the <tt>[[#setool|setool]]</tt> output), or the <tt>"@.."</tt> format as shown in the example below, the signature will then be automatically generated as part of the build process by <tt>[[#insertkeys.py|insertkeys.py]]</tt> as described in [[NB_SEforAndroid_1#Building the Policy| Building the Policy]] section. It is recommended that a signature is always present. | ||
+ | ** Zero or more <tt><nowiki><export-read value="" /></nowiki></tt> entries defining the read protection level (<tt>protectionLevel=</tt> in manifest). These are defined as <tt>normal</tt>, <tt>dangerous</tt>, <tt>signature</tt> or <tt>signatureOrSystem</tt>). | ||
+ | ** Zero or more <tt><nowiki><export-write value="" /></nowiki></tt> entries defining the write protection level (as <tt>export-read</tt> above). | ||
+ | * <tt><nowiki></type></nowiki></tt> end tag. | ||
+ | |||
+ | When computing access to content the following precedence rules apply to content type entries: | ||
+ | |||
+ | # Signature defined over signature not defined. | ||
+ | # Provider defined over provider not defined. | ||
+ | # Package name defined over package name not defined. | ||
+ | |||
+ | There is no distinction between a stanza that has more signatures than another. They are considered of equal precedence. | ||
Example entries are: | Example entries are: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <policy> | ||
+ | <type name="browser_exported_provider"> | ||
+ | <signature value="@RELEASE"/> | ||
+ | <provider value="com.android.browser"/> | ||
+ | <provider value="browser"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="browser_protected_provider"> | ||
+ | <signature value="@RELEASE"/> | ||
+ | <provider value="com.android.browser.home"/> | ||
+ | <provider value="com.android.browser.snapshots"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="platform_default_provider"> | ||
+ | <signature value="@PLATFORM"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="shared_default_provider"> | ||
+ | <signature value="@SHARED"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="media_default_provider"> | ||
+ | <signature value="@MEDIA"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="release_default_provider"> | ||
+ | <signature value="@RELEASE"/> | ||
+ | </type> | ||
+ | |||
+ | <type name="default_provider"> | ||
+ | </type> | ||
+ | |||
+ | <type name="demo_provider"> | ||
+ | <package value="com.se4android.contentprovider" /> | ||
+ | <signature value="@RELEASE"/> | ||
+ | <provider value="com.se4android.contentprovider.contentproviderdemo"/> | ||
+ | <export-read value="normal" /> | ||
+ | <export-write value="dangerous" /> | ||
+ | </type> | ||
+ | <policy> | ||
+ | </pre> | ||
+ | |||
+ | === Attribute Entries === | ||
+ | The <tt>content_provider.xml</tt> file attribute entries consist of: | ||
+ | |||
+ | * <tt><nowiki><attributes></nowiki></tt> start tag. | ||
+ | ** Zero or more <tt><nowiki><attribute name="" ></nowiki></tt> entries. The <tt>name=</tt> entry defines the group name used to reference all the <tt><nowiki><type></nowiki></tt> entries. The <tt>name=</tt> may then be used in <tt><nowiki><allow></nowiki></tt> <tt>source=</tt> (for groups of package types) or <tt>destination=</tt> (for groups of content types) entries. | ||
+ | *** Zero or more <tt><nowiki><type name="" /></nowiki></tt> entries. The <tt>name=</tt> entry refers to a package or content type entry. | ||
+ | ** <tt><nowiki></attribute></nowiki></tt> end tag. | ||
+ | * <tt><nowiki></attributes></nowiki></tt> end tag. | ||
+ | |||
+ | Example <tt><nowiki><attributes></nowiki></tt> entry: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <policy> | ||
+ | <attributes> | ||
+ | <attribute name="all"> | ||
+ | <type name="platform"/> | ||
+ | <type name="release"/> | ||
+ | <type name="shared"/> | ||
+ | <type name="gapps"/> | ||
+ | <type name="media"/> | ||
+ | <type name="vpn"/> | ||
+ | <type name="default"/> | ||
+ | </attribute> | ||
+ | |||
+ | <attribute name="trusted_apps"> | ||
+ | <type name="platform"/> | ||
+ | <type name="release"/> | ||
+ | <type name="shared"/> | ||
+ | <type name="gapps"/> | ||
+ | <type name="media"/> | ||
+ | </attribute> | ||
+ | |||
+ | <attribute name="all_media_provider"> | ||
+ | <type name="media_provider"/> | ||
+ | <type name="drm_provider"/> | ||
+ | </attribute> | ||
+ | </attributes> | ||
+ | </policy> | ||
+ | </pre> | ||
+ | |||
+ | === allow-content Entry === | ||
+ | The <tt>content_provider.xml</tt> file allow content entries consist of: | ||
+ | |||
+ | * <tt><nowiki><allow-content></nowiki></tt> start tag. | ||
+ | ** Zero of more <tt><nowiki><allow</nowiki></tt> entries that consist of the following: | ||
+ | *** A <tt>source=""</tt> reference to a package type entry. | ||
+ | *** A <tt>destination=""</tt> reference to a content type entry. | ||
+ | *** A <tt>permission=""</tt> entry stating that the <tt>source=</tt> reference may use (<tt>use</tt>), read (<tt>r</tt>), write (<tt>w</tt>) or read/write (<tt>rw</tt>) the <tt>destination=</tt> content provider. Each permission is separated by a semi-colon (<tt><nowiki>;</nowiki></tt>). The <tt>use</tt> permission is required to obtain a handle to the content provider, but does not provide read or write capability. Read, Write, or Read-Write imply the <tt>use</tt> permission. | ||
+ | ** <tt>/></tt> The <tt>allow</tt> end tag. | ||
+ | * <tt><nowiki></allow-content></nowiki></tt> end tag. | ||
+ | |||
+ | Example <tt><nowiki><allow-content></nowiki></tt> entry: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <policy> | ||
+ | <allow-content> | ||
+ | <allow source="all" destination="settings_provider" permission="use;r"/> | ||
+ | <allow source="trusted_apps" destination="all_contacts_provider" permission="use;r"/> | ||
+ | <allow source="platform" destination="media_provider" permission="use;rw"/> | ||
+ | <allow source="release" destination="mms_sms_provider" permission="use;rw"/> | ||
+ | <allow source="release" destination="browser_exported_provider" permission="use;rw"/> | ||
+ | <allow source="release" destination="all_calendar_provider" permission="use;r"/> | ||
+ | <allow source="release" destination="all_email_provider" permission="use;r"/> | ||
+ | <allow source="platform" destination="all_telephony_provider" permission="use;r"/> | ||
+ | <allow source="release" destination="search_provider" permission="use;r"/> | ||
+ | <allow source="release" destination="media_provider" permission="use;rw"/> | ||
+ | <allow source="shared" destination="dictionary_provider" permission="use;r"/> | ||
+ | <allow source="shared" destination="email_attach_provider" permission="use;r"/> | ||
+ | <allow source="demo_resolver_package" destination="demo_provider" permission="use;rw"/> | ||
+ | <allow source="demo_resolver_package" destination="settings_provider" permission="use;r"/> | ||
+ | </allow-content> | ||
+ | </policy> | ||
+ | </pre> | ||
+ | |||
+ | == Revoke Permissions MMAC Configuration File == | ||
+ | The <tt>revoke_permissions.xml</tt> file is used to configure revoked permissions. The build process does not currently support additional files. | ||
+ | |||
+ | All entries are between <tt><nowiki><revoke-policy></nowiki></tt> tags: | ||
<pre> | <pre> | ||
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
<revoke-policy> | <revoke-policy> | ||
+ | ...... | ||
+ | </revoke-policy> | ||
+ | </pre> | ||
− | + | The <tt>revoke_permissions.xml</tt> file entries are as follows: | |
− | + | ||
− | + | ||
− | + | * <tt><nowiki><package name="" ></nowiki></tt> entry. The <tt>name=</tt> refers to the package name. | |
− | + | ** One or more <tt><nowiki><revoke-permission name="" /></nowiki></tt> entries. The <tt>name=</tt> refers to the permission to be denied. | |
− | + | * <tt><nowiki></package></nowiki></tt> end tag. | |
+ | An example entry is: | ||
+ | <pre> | ||
+ | <?xml version="1.0" encoding="utf-8"?> | ||
+ | <revoke-policy> | ||
+ | <package name="com.example.runisolatedservice "> | ||
+ | <revoke-permission name="com.se4android.isolatedservice.permission.DEADLY_ACTIVITY"/> | ||
+ | </package> | ||
</revoke-policy> | </revoke-policy> | ||
</pre> | </pre> | ||
+ | |||
= Policy Build Tools = | = Policy Build Tools = | ||
Line 728: | Line 977: | ||
== insertkeys.py == | == insertkeys.py == | ||
− | The <tt>insertkeys.py</tt> utility is used during the build process to insert signing keys into multiple <tt>mac_permissions.xml</tt> | + | The <tt>insertkeys.py</tt> utility is used during the build process to insert signing keys into multiple <tt>mac_permissions.xml</tt>, <tt>mmac_types.xml</tt> and <tt>content_provider.xml</tt> files. The keys are obtained from <tt>pem</tt> files and the entries to be replaced start with an <tt>@</tt> followed by a keyword. The <tt>external/sepolicy/keys.conf</tt> file contains corresponding entries that allow mapping of <tt>pem</tt> files to signatures as discussed in the [[#keys.conf | keys.conf]] section. |
Note that <tt>pem</tt> files are base64 encoded however the Android Package Manager Service uses base16 encodings. Therefore <tt>insertkeys.py</tt> and <tt>setool</tt> will generate base16 encodings for the <tt>mac_permissions.xml</tt> and <tt>mmac_types.xml</tt> files. | Note that <tt>pem</tt> files are base64 encoded however the Android Package Manager Service uses base16 encodings. Therefore <tt>insertkeys.py</tt> and <tt>setool</tt> will generate base16 encodings for the <tt>mac_permissions.xml</tt> and <tt>mmac_types.xml</tt> files. | ||
Line 734: | Line 983: | ||
<tt>insertkeys.py</tt> will also strip the files of comments and whitespace to preserve space on the <tt>system.img</tt>. To view the output file in a more human friendly format the <tt>tidy</tt> or <tt>xmllint</tt> command can be used. | <tt>insertkeys.py</tt> will also strip the files of comments and whitespace to preserve space on the <tt>system.img</tt>. To view the output file in a more human friendly format the <tt>tidy</tt> or <tt>xmllint</tt> command can be used. | ||
− | <tt>insertkeys.py -h</tt> will give the following output: | + | <tt>insertkeys.py -h</tt> will give the following output for 4.3 (4.2 does not have the <tt>-d</tt> option): |
<pre> | <pre> | ||
− | + | Usage: insertkeys.py [options] CONFIG_FILE MAC_PERMISSIONS_FILE [MAC_PERMISSIONS_FILE...] | |
This tool allows one to configure an automatic inclusion of signing keys into the mac_permission.xml file(s) from the pem files. | This tool allows one to configure an automatic inclusion of signing keys into the mac_permission.xml file(s) from the pem files. | ||
Line 749: | Line 998: | ||
-t TARGET_BUILD_VARIANT, --target-build-variant=TARGET_BUILD_VARIANT | -t TARGET_BUILD_VARIANT, --target-build-variant=TARGET_BUILD_VARIANT | ||
Specify the TARGET_BUILD_VARIANT, defaults to eng | Specify the TARGET_BUILD_VARIANT, defaults to eng | ||
+ | -d KEY_DIRECTORY, --key-directory | ||
+ | Specify a parent directory for keys | ||
</pre> | </pre> | ||
Line 762: | Line 1,013: | ||
<tt>insertkeys.py</tt> allows for mapping any string contained in <tt>TARGET_BUILD_VARIANT</tt> with a specific path to a <tt>pem</tt> file. Typically <tt>TARGET_BUILD_VARIANT</tt> is either <tt>user</tt>, <tt>eng</tt> or <tt>userdebug</tt>. Additionally "<tt>ALL</tt>" may be specified to map a path to any string specified in <tt>TARGET_BUILD_VARIANT</tt>. All tags are matched verbatim and all options are matched lowercase. The options are "<tt>tolowered</tt>" automatically for the user, it is convention to specify tags and options in all uppercase and tags start with <tt>@</tt>. | <tt>insertkeys.py</tt> allows for mapping any string contained in <tt>TARGET_BUILD_VARIANT</tt> with a specific path to a <tt>pem</tt> file. Typically <tt>TARGET_BUILD_VARIANT</tt> is either <tt>user</tt>, <tt>eng</tt> or <tt>userdebug</tt>. Additionally "<tt>ALL</tt>" may be specified to map a path to any string specified in <tt>TARGET_BUILD_VARIANT</tt>. All tags are matched verbatim and all options are matched lowercase. The options are "<tt>tolowered</tt>" automatically for the user, it is convention to specify tags and options in all uppercase and tags start with <tt>@</tt>. | ||
− | An example <tt>keys.conf</tt> file is as follows: | + | An example <tt>keys.conf</tt> file for AOSP 4.3 is as follows (note that the path is now supplied by the <tt>-d</tt> option when calling <tt>insertkeys.py</tt> in the <tt>external/sepolicy/Android.mk</tt> file): |
<pre> | <pre> | ||
− | + | # | |
− | + | # Maps an arbitrary tag [TAGNAME] with the string contents found in | |
− | + | # TARGET_BUILD_VARAINT. Common convention is to start TAGNAME with an @ and | |
− | + | # name it after the base file name of the pem file. | |
− | + | # | |
− | + | # Each tag (section) then allows one to specify any string found in | |
− | + | # TARGET_BUILD_VARIANT. Typically this is user, eng, and userdebug. Another | |
− | + | # option is to use ALL which will match ANY TARGET_BUILD_VARAINT string. | |
− | + | # | |
− | + | [@PLATFORM] | |
− | ALL : | + | ALL : platform.x509.pem |
− | + | [@MEDIA] | |
− | ALL : | + | ALL : media.x509.pem |
− | + | [@SHARED] | |
− | ALL : | + | ALL : shared.x509.pem |
− | + | # Example of ALL TARGET_BUILD_VARIANTS | |
− | < | + | [@RELEASE] |
− | + | ENG : testkey.x509.pem | |
− | + | USER : testkey.x509.pem | |
− | + | USERDEBUG : testkey.x509.pem | |
+ | </pre> | ||
+ | |||
+ | The following is an example entry that will use a device specific key for release 4.3 during the build process: | ||
+ | <pre> | ||
+ | [@NET_APPS] | ||
+ | ALL : $ANDROID_BUILD_TOP/device/demo_vendor/demo_device/security/net_apps.x509.pem | ||
+ | </pre> | ||
+ | |||
+ | Should the build fail because of keys.conf entries, check that the following patch is installed: | ||
+ | |||
+ | [https://android-review.googlesource.com/#/c/63370/ https://android-review.googlesource.com/#/c/63370/] | ||
+ | |||
+ | If using 4.2, then a device specific example entry would be: | ||
+ | <pre> | ||
+ | [@NET_APPS] | ||
+ | ALL : device/demo_vendor/demo_device/security/net_apps.x509.pem | ||
+ | </pre> | ||
+ | |||
+ | == buildsebundle == | ||
+ | The following text has been extracted from an email that describes this new 4.3 feature: | ||
+ | New code has been released that allow for policy reloading via Android's new UpdateConfig mechanism. Android 4.3 has brought a new set of OTA update hooks for various policy files including some of the SELinux ones. This is a way forward with reloadable policy support and as such have updated the SEAdmin project (master and seandroid-4.3 branches) with a new but limited reload option as well as updated the sepolicy project (seandroid and seandroid-4.3 branches) with new tooling. Some things to note: | ||
+ | * In order for SEAdmin to reload policy there is a required format imposed by the backed ConfigUpdate code. A new signed policy 'bundle' and metadata file are required; the bundle being a packed version of various selinux policy files. Because of this new format, a new tool called buildsebundle has been developed that will help with the construction of such files. It is not built as standard, therefore need to 'make buildsebundle' first and then see the help menu below along with an example. | ||
+ | * buildsebundle actually outputs a zip file containing the packed bundle and metadata file. The zip file isn't a direct requirement for the ConfigUpdate code but merely serves as a convenient packaging format to deliver both files to the device. This zip file will need to be pushed to /sdcard for SEAdmin to reload it. | ||
+ | * There is a requirement that the resulting bundle be signed for integrity purposes. The buildsebundle tool will help with this but a few caveats are in order. The backend code on the phone requires that an approved OTA cert already be loaded into the Settings secure database to verify the incoming reload request. This means that the cert on the phone must match the key fed the buildsebundle tool. SEAdmin has been changed to insert a key by first reading the entries in otacerts.zip on boot. The otacerts.zip file will include the correct testkey/releasekey when building the system image. | ||
+ | * There is no support for reloading mac_permissions.xml via this new reload mechanism. This is a limitation of the back end code which only supports reloading file_contexts, sepolicy, property_contexts and seapp_contexts policy files. The previous option for reloading mac_permissions.xml remains supported in the SEAdmin app however. The project will also continue to support the SEAdmin app as the ConfigUpdate code doesn't presently offer the abilities to switch to enforcing mode or toggle booleans. | ||
+ | * AOSP code for the new update mechanism can be found at: <tt>frameworks/base/services/java/com/android/server/updates/*</tt> . | ||
+ | * Since the ConfigUpdate code seems to still be under development, the SEAndroid project will most likely move in-step with that code in order to bring ideas together whenever possible. So, updates to both the SEAdmin and sepolicy tooling are possible in the future. | ||
+ | |||
+ | |||
+ | <tt>buildsebundle -h</tt> will give the following output: | ||
+ | <pre> | ||
+ | usage: buildsebundle -k <private key.pk8> [-v <version>] [-r <previous hash>] [-h] -- <file_contexts> | ||
+ | <property_contexts> <sepolicy> <seapp_contexts> | ||
+ | |||
+ | This script builds a selinux policy bundle and supporting metadata file capable of being loaded via | ||
+ | the ConfigUpdate mechanism. It takes a pkcs8 DER encoded RSA private key that is then used to sign | ||
+ | the bundle. For AOSP development you'll typically want to use the key from the source tree at | ||
+ | build/target/product/security/testkey.pk8. If building your own cert you should probably use at least | ||
+ | a key size of 1024 or greater. The bundle requires that seapp_contexts, file_contexts, property_contexts | ||
+ | and sepolicy files all be included and with those exact basenames. The built bundle will be written to | ||
+ | selinux_bundle.zip which will include the signature metadata file of the bundle. | ||
+ | |||
+ | OPTIONS: | ||
+ | -h Show this message. | ||
+ | -v Version of the built bundle. Defaults to 1. | ||
+ | -r Sha512 hash of the bundle to replace. Defaults to 'NONE'. | ||
+ | </pre> | ||
+ | |||
+ | The following example (with policy files in <tt>cwd</tt> will produce an <tt>selinux_bundle.zip</tt> file containing two files <tt>update_bundle</tt> and <tt>update_bundle_metadata</tt>: | ||
+ | <pre> | ||
+ | buildsebundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -- file_contexts \ | ||
+ | property_contexts sepolicy seapp_contexts | ||
</pre> | </pre> | ||
== setool == | == setool == | ||
− | The <tt>setool</tt> utility is not used during the build process and is intended only to produce 'starter' entries for the <tt>mac_permissions.xml</tt> file. | + | The <tt>setool</tt> utility is not used during the build process and is intended only to produce 'starter' entries for the <tt>mac_permissions.xml</tt> file. It is not supplied in AOSP. |
The entries produced will generally have to be modified because currently: | The entries produced will generally have to be modified because currently: | ||
− | # If multiple packages are given each with the same signature, a separate entry will be generated for each package. If added to the <tt>mac_permissions.xml</tt> file only the first entry will be used by the Install | + | # If multiple packages are given each with the same signature, a separate entry will be generated for each package. If added to the <tt>mac_permissions.xml</tt> file only the first entry will be used by the Install MMAC process (therefore the packages need to be consolidated into on entry). |
− | # <tt>setool</tt> will generate (<tt>--build</tt>) entries for third party apps, however it should not as they will be ignored by the | + | # <tt>setool</tt> will generate (<tt>--build</tt>) entries for third party apps, however it should not as they will be ignored by the Install MMAC. |
# <tt>setool</tt> will check (<tt>--policy</tt>) third party apps against the full <tt>mac_permissions.xml</tt> policy, however it should not, it should only check them against the <tt><nowiki><default></nowiki></tt> entries only. | # <tt>setool</tt> will check (<tt>--policy</tt>) third party apps against the full <tt>mac_permissions.xml</tt> policy, however it should not, it should only check them against the <tt><nowiki><default></nowiki></tt> entries only. | ||
Line 826: | Line 1,129: | ||
</pre> | </pre> | ||
− | The following are examples of using <tt>setool</tt> | + | The following are examples of using <tt>setool</tt>: |
− | + | ||
− | + | ||
<pre> | <pre> | ||
− | setool | + | setool --build whitelist RunIsolatedService.apk > demo/ mac_permissions.xml |
</pre> | </pre> | ||
Line 836: | Line 1,137: | ||
<pre> | <pre> | ||
<signer signature="- key will be here -"> | <signer signature="- key will be here -"> | ||
− | <package name="com.example. | + | <package name="com.example.runisolatedservice"> |
− | + | <allow-permission name="com.se4android.isolatedservice.permission.DEADLY_ACTIVITY" /> | |
− | + | ||
− | + | ||
− | <allow-permission name="com. | + | |
− | + | ||
</package> | </package> | ||
</signer> | </signer> | ||
</pre> | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
= uid To username Utility = | = uid To username Utility = |
Revision as of 14:29, 29 August 2013
Contents
Policy File Configuration Details
This section details the specific SE for Android policy configuration files (i.e. those not used by 'standard' Linux based SELinux). Where those files are used to compute contexts using the SE for Android libselinux functions, those functions are also described with examples.
As this project is continually being enhanced, it is recommended that the official project wiki is checked for the latest enhancements at SEforAndroid
SELinux MAC Configuration Files
seapp_contexts File
This file is loaded and sorted into memory automatically on first use of one of the following SE for Android libselinux functions that are called by the SE for Android enabled services:
- selinux_android_setcontext - Computes process security contexts.
- selinux_android_setfilecon2 - Computes file/directory security contexts.
selinux_android_seapp_context_reload will also reload this file.
The build process supports additional seapp_contexts files to allow devices to specify their specific entries as described in the Building the Policy section.
The following sections will show:
- The default external/sepolicy/seapp_contexts file entries.
- A description of the seapp_contexts entries and their usage.
- A brief description of how a context is computed using either the selinux_android_setcontext or selinux_android_ setfilecon2 function using the seapp_contexts file entries.
- Examples of computed domain and directory contexts for various apps.
Default Entries
The default external/sepolicy/seapp_contexts file contains the following entries:
isSystemServer=true domain=system user=system domain=system_app type=system_data_file user=bluetooth domain=bluetooth type=bluetooth_data_file user=nfc domain=nfc type=nfc_data_file user=radio domain=radio type=radio_data_file user=_app domain=untrusted_app type=app_data_file levelFrom=app user=_app seinfo=platform domain=platform_app type=platform_app_data_file user=_app seinfo=shared domain=shared_app type=platform_app_data_file user=_app seinfo=media domain=media_app type=platform_app_data_file user=_app seinfo=release domain=release_app type=platform_app_data_file user=_isolated domain=isolated_app
Entry Definitions
The following has been extracted from the default file with some additional comments that describe the parameters and how they are used to compute a context:
Input selectors from seapp_contexts file:
- isSystemServer (boolean)
- user (string)
- seinfo (string)
- name (string) - A package name e.g. com.example.demo
- sebool (string) - The boolean must be ‘active’ (enabled/true)
isSystemServer=true can only be used once. An unspecified isSystemServer defaults to false.
An unspecified string selector will match any value.
A user string selector that ends in * will perform a prefix match.
user=_app will match any regular app UID.
user=_isolated will match any isolated service UID.
All specified input selectors in an entry must match (i.e. logical AND).
Matching is case-insensitive.
Precedence rules:
- 1) isSystemServer=true before isSystemServer=false.
- 2) Specified user= string before unspecified user= string.
- 3) Fixed user= string before user= prefix (i.e. ending in *).
- 4) Longer user= prefix before shorter user= prefix.
- 5) Specified seinfo= string before unspecified seinfo= string.
- 6) Specified name= string before unspecified name= string.
- 7) Specified sebool= string before unspecified sebool= string.
Outputs:
- domain (string) - The type component of a process context.
- type (string) - The type component of a file/directory context.
- levelFrom (string; one of none, all, app, or user) - A level that will be automatically computed based on the parameter.
- level (string) - A predefined level (e.g. s0:c1022.c1023)
Only entries that specify domain= will be used for app process labeling.
Only entries that specify type= will be used for app directory labeling.
levelFrom=user is only supported for _app or _isolated UIDs.
levelFrom=app or levelFrom=all is only supported for _app UIDs.
level may be used to specify a fixed level for any UID.
Computing a Process Context
To compute an app process context the selinux_android_setcontext function is called that will use the parameters passed, plus the contents of the seapp_contexts file. The function parameters are:
#include <selinux/android.h> int selinux_android_setcontext(uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname);
The context is then computed using the information as follows:
- The uid is converted to a string that is then used to match the user= entries in the seapp_contexts file as follows:
- If an Android system service the uid is converted to a string via an internal Android table (e.g. "radio", "system").
- If an isolated service the _isolated string is used.
- For any other app or service the _app is used.
- The isSystemServer value must match that set in the running system and be true or false. It will be matched against the isSystemServer= entries in the seapp_contexts file.
- seinfo may be NULL or that obtained from the mac_permissions.xml file. It will be matched against the seinfo= entries in the seapp_contexts file.
- pkgname may be NULL or that obtained from the Android package. It will be matched against the name= entries in the seapp_contexts file.
- The remaining seapp_contexts entries will be used as follows:
- The sebool= parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
- The levelFrom= and level= parameters if present will be used to determine the level component of the security context.
- The domain= is used to set the process context and must match a context in the policy. Determines the type component of the security context.
If a context is computed, it is validated against policy and if correct setcon(3) will then be used to set the process context.
Examples The following is an example taken as the system server is loaded:
Input selectors: uid 1000 isSystemServer true seinfo null name null sebool null username computed from uid = system Matching seapp_contexts entry: isSystemServer=true domain=system Outputs: domain system level s0 Computed context u:r:system:s0 Result using ps -Z command: LABEL USER PID PPID NAME u:r:system:s0 system 300 45 system_server
This is the "radio" application that is part of the platform:
Input selectors: uid 1001 isSystemServer false seinfo platform name com.android.phone sebool null username computed from uid = radio Matching seapp_contexts entry: user=radio domain=radio type=radio_data_file Outputs: domain radio level s0 Computed context u:r:radio:s0 Result using ps -Z command: LABEL USER PID PPID NAME u:r:radio:s0 radio 443 45 com.android.phone
This is the "SE for Android Admin Manager" application that is part of the platform:
Input selectors: uid 10042 isSystemServer false seinfo release name com.android.seandroid_admin sebool null username computed from uid = u0_a42 Matching seapp_contexts entry: user=_app seinfo=release domain=release_app type=platform_app_data_file Outputs: domain release_app level s0 Computed context u:r:release_app:s0 Result using ps -Z command: LABEL USER PID PPID NAME u:r:release_app:s0 u0_a42 827 45 com.android.seandroid_admin
This is a third party app that also runs an isolated service:
Input selectors: uid 10046 isSystemServer false seinfo null name com.example.seandroiddemo sebool null username computed from uid = u0_a46 Matching seapp_contexts entry: user=_app domain=untrusted_app type=app_data_file levelFrom=app Outputs: domain untrusted_app levelFrom app s0:c46,c256 Computed context u:r:untrusted_app:s0:c46,c256 Result using ps -Z command: LABEL USER PID PPID NAME u:r:untrusted_app:s0:c46,c256 u0_a46 855 45 com.example.seandroiddemo
Input selectors: uid 99000 isSystemServer false seinfo null name com.example.seandroiddemo sebool null username computed from uid = u0_i0 Matching seapp_contexts entry: user=_isolated domain=isolated_app Outputs: domain isolated_app level s0 Computed context u:r:isolated_app:s0 Result using ps -Z command: LABEL USER PID PPID NAME u:r:isolated_app:s0 u0_i0 869 45 com.example.seandroiddemo
Computing a Directory Context
To compute an app package directory context the selinux_android_setfilecon2 function is called that will use the parameters passed, plus the contents of the seapp_contexts file. The function parameters are:
#include <selinux/android.h> int selinux_android_setfilecon2(const char *pkgdir, const char *pkgname, const char *seinfo, uid_t uid);
The context is then computed using the information as follows:
- pkgdir is the file or directory to be labeled with the computed context.
- pkgname may be NULL or that obtained from the Android package. It will be matched against the name= entries in the seapp_contexts file.
- seinfo may be NULL or that obtained from the mac_permissions.xml file. It will be matched against the seinfo= entries in the seapp_contexts file.
- The uid is converted to a string that is then used to match the user= entries in the seapp_contexts file as follows:
- If an Android system service the uid is converted to a string via an internal Android table (e.g. "radio", "system").
- If an isolated service the _isolated string is used.
- For any other app or service the _app is used.
- The remaining seapp_contexts entries will be used as follows:
- The sebool= parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
- The levelFrom= and level= parameters if present will be used to determine the level component of the security context.
- The type= is used to set the file object context and must match a context in the policy. Determines the type component of the security context.
If a context is computed, it is validated against policy and if correct setfilecon(3) will then be used to label pkgdir with the computed context. The following example is from a third party app:
Input selectors: uid 10046 isSystemServer false seinfo null name com.example.seandroiddemo sebool null pkgdir /data/data/com.example.seandroiddemo username computed from uid = u0_a46 Matching seapp_contexts entry: user=_app domain=untrusted_app type=app_data_file levelFrom=app Outputs: type app_data_file levelFrom app s0:c46,c256 Computed context u:object_r:app_data_file:s0:c46,c256 Result from /data/data directory using ls -Z command: drwxr-x--x u0_a46 u0_a46 u:object_r:app_data_file:s0:c46,c256 com.example.seandroiddemo
Example ls -Z /data/data entries:
drwxr-x--x u0_a35 u0_a35 u:object_r:platform_app_data_file:s0 com.android.backupconfirm drwxr-x--x bluetooth bluetooth u:object_r:bluetooth_data_file:s0 com.android.bluetooth drwxr-x--x u0_a7 u0_a7 u:object_r:platform_app_data_file:s0 com.android.browser drwxr-x--x u0_a37 u0_a37 u:object_r:platform_app_data_file:s0 com.android.deskclock drwxr-x--x u0_a21 u0_a21 u:object_r:platform_app_data_file:s0 com.android.development drwxr-x--x u0_a30 u0_a30 u:object_r:platform_app_data_file:s0 com.android.mms drwxr-x--x u0_a19 u0_a19 u:object_r:platform_app_data_file:s0 com.android.music drwxr-x--x u0_a31 u0_a31 u:object_r:platform_app_data_file:s0 com.android.musicfx drwxr-x--x u0_a5 u0_a5 u:object_r:platform_app_data_file:s0 com.android.musicvis drwxr-x--x u0_a17 u0_a17 u:object_r:platform_app_data_file:s0 com.android.noisefield drwxr-x--x system system u:object_r:system_data_file:s0 com.android.providers.settings drwxr-x--x radio radio u:object_r:radio_data_file:s0 com.android.providers.telephony drwxr-x--x u0_a0 u0_a0 u:object_r:platform_app_data_file:s0 com.android.provision drwxr-x--x u0_a34 u0_a34 u:object_r:platform_app_data_file:s0 com.android.quicksearchbox drwxr-x--x u0_a42 u0_a42 u:object_r:platform_app_data_file:s0 com.android.seandroid_admin drwxr-x--x system system u:object_r:system_data_file:s0 com.android.settings drwxr-x--x u0_a14 u0_a14 u:object_r:platform_app_data_file:s0 com.android.smspush drwxr-x--x u0_a26 u0_a26 u:object_r:platform_app_data_file:s0 com.android.soundrecorder drwxr-x--x u0_a2 u0_a2 u:object_r:platform_app_data_file:s0 com.android.speechrecorder drwxr-x--x u0_a4 u0_a4 u:object_r:platform_app_data_file:s0 com.android.systemui drwxr-x--x u0_a11 u0_a11 u:object_r:platform_app_data_file:s0 com.android.videoeditor drwxr-x--x u0_a12 u0_a12 u:object_r:platform_app_data_file:s0 com.android.voicedialer drwxr-x--x u0_a10 u0_a10 u:object_r:platform_app_data_file:s0 com.android.vpndialogs drwxr-x--x u0_a16 u0_a16 u:object_r:platform_app_data_file:s0 com.android.wallpaper drwxr-x--x u0_a46 u0_a46 u:object_r:app_data_file:s0:c46,c256 com.example.seandroiddemo
property_contexts File
This file holds property names and their contexts that will be applied by SELinux when applications are loaded. The property names reflect the 'white list' of Android property entries that are also built into the system (see system/core/init/property_service.c and init.c) however there are also additional property entries for applications that require specific contexts to be set.
The build process supports additional seapp_contexts files to allow devices to specify their specific entries as described in the Building the Policy section.
When selabel_open(3) is called specifying this file it will be read into memory and sorted using qsort(3), subsequent calls using selabel_lookup(3) will then retrieve the appropriate context.
Each line within the property contexts file is as follows:
property_key context
Where:
- property_key
- The key used to obtain the context that may contain '*' for wildcard matching.
- context
- The security context that will be applied to the object.
The default property_contexts file entries are:
########################## # property service keys # net.rmnet0 u:object_r:radio_prop:s0 net.gprs u:object_r:radio_prop:s0 net.ppp u:object_r:radio_prop:s0 net.qmi u:object_r:radio_prop:s0 net.lte u:object_r:radio_prop:s0 net.cdma u:object_r:radio_prop:s0 gsm. u:object_r:radio_prop:s0 persist.radio u:object_r:radio_prop:s0 net.dns u:object_r:radio_prop:s0 sys.usb.config u:object_r:radio_prop:s0 ril. u:object_r:rild_prop:s0 net. u:object_r:system_prop:s0 dev. u:object_r:system_prop:s0 runtime. u:object_r:system_prop:s0 hw. u:object_r:system_prop:s0 sys. u:object_r:system_prop:s0 service. u:object_r:system_prop:s0 wlan. u:object_r:system_prop:s0 dhcp. u:object_r:system_prop:s0 debug. u:object_r:shell_prop:s0 log. u:object_r:shell_prop:s0 service.adb.root u:object_r:shell_prop:s0 service.adb.tcp.port u:object_r:shell_prop:s0 persist.audio. u:object_r:audio_prop:s0 persist.sys. u:object_r:system_prop:s0 persist.service. u:object_r:system_prop:s0 persist.security. u:object_r:system_prop:s0 # mmac persistent properties persist.mmac.u:object_r:security_prop:s0 # selinux non-persistent properties selinux. u:object_r:security_prop:s0 # default property context * u:object_r:default_prop:s0 # data partition encryption properties vold. u:object_r:vold_prop:s0 crypto. u:object_r:vold_prop:s0 # ctl properties ctl.dumpstate u:object_r:ctl_dumpstate_prop:s0 ctl.ril-daemon u:object_r:ctl_rildaemon_prop:s0 ctl. u:object_r:ctl_default_prop:s0
Install MMAC Configuration File
The mac_permissions.xml file is used to configure Install MMAC policy and provides two main functions:
- x.509 certificate to seinfo string mapping so that Zygote spawns the application in the correct domain. See the Computing a Process Context section for how this is achieved using information also contained in the seapp_contexts file (AOSP and SEAndroid).
- Install MMAC permission checking (SEAndroid only).
It is important to note that all third party apps will be subject to the <default> install MMAC policy defined in this file. This is a requirement of AOSP in that all third party apps must be treated alike (i.e. distinctions can only be made between system apps and third party apps and among the system apps, not between two different third party apps).
An example AOSP mac_permissions.xml file that also shows the <default> entry is:
<?xml version="1.0" encoding="utf-8"?> <policy> <!-- Platform dev key in AOSP --> <signer signature="@PLATFORM" > <seinfo value="platform" /> </signer> <!-- Media dev key in AOSP --> <signer signature="@MEDIA" > <seinfo value="media" /> </signer> <!-- shared dev key in AOSP --> <signer signature="@SHARED" > <seinfo value="shared" /> </signer> <!-- release dev key in AOSP --> <signer signature="@RELEASE" > <seinfo value="release" /> </signer> <!-- All other keys --> <default> <seinfo value="default" /> </default> </policy>
An example SEAndroid <default> package policy is:
<!-- All other keys --> <default> <seinfo value="default" /></nowiki> <deny-permission name="android.permission.ACCESS_COARSE_LOCATION" /> <deny-permission name="android.permission.ACCESS_FINE_LOCATION" /> <deny-permission name="android.permission.AUTHENTICATE_ACCOUNTS" /> <deny-permission name="android.permission.CALL_PHONE" /> <deny-permission name="android.permission.CAMERA" /> <deny-permission name="android.permission.READ_LOGS" /> <deny-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> </default>>
The build process supports additional mac_permissions.xml files to allow devices to specify their specific entries as described in the Building the Policy section.
Signature Entries
The <signer signature= entry may have the public base16 signing key present in the string or it may have an entry starting with @ then a keyword (e.g @PLATFORM) that will signify that the key is to be extracted from a pem file as discussed in the insertkeys.py section:
<!-- Platform dev key in AOSP --> <signer signature="@PLATFORM" > <allow-all /> <seinfo value="platform" /> </signer>
If a base16 key is required, it can be extracted from a package using the setool utility as described in the setool section.
Policy Rules
The following rules have been extracted from the SEAndroid mac_permissions.xml file:
- A signature is a hex encoded X.509 certificate and is required for each signer tag.
- A <signer signature="" > element may have multiple child elements:
- allow-permission : produces a set of maximal allowed permissions (whitelist).
- deny-permission : produces a blacklist of permissions to deny.
- allow-all : a wildcard tag that will allow every permission requested.
- package : a complex tag which itself defines allow, deny, and wildcard sub elements for a specific package name protected by the signature.
- Zero or more global <package name=""> tags are allowed. These tags allow a policy to be set outside any signature for specific package names.
- Unknown tags at any level are skipped.
- Zero or more signer tags are allowed.
- Zero or more package tags are allowed per signer tag.
- A <package name=""> tag may not contain another <package name=""> tag. If found, it's skipped.
- A <default> tag is allowed that can contain install policy for all apps not signed with a previously listed cert and not having a per package global policy.
- When multiple sub elements appear for a tag the following logic is used to ultimately determine the type of enforcement:
- A blacklist is used if at least one deny-permission tag is found
- A whitelist is used if not a blacklist and at least one allow-permission tag is found
- A wildcard (accept all permission) policy is used if not a blacklist and not a whitelist and at least one allow-all tag is present.
- If a <package name=""> sub element is found then that sub element's policy is used according to the above logic and overrides any signature global policy type.
- In order for a policy stanza to be enforced at least one of the above situations must apply. Meaning, empty signer, default or package tags will not be accepted.
- Each signer / default / global package tag is allowed to contain one <seinfo value=""/> tag. This tag represents additional information that each application can use in setting a SELinux security context on the eventual process. Any <seinfo value=""/> tag found as a child of a <package name=""> tag which is protected (sub element of signer or the default tag) is ignored. It's possible that multiple seinfo tags are relevant for one application. In the event that this happens, the seinfo tag that will be applied is the one for which the corresponding policy stanza is used in the policy decision.
- Strict enforcing of any xml stanza is not enforced in most cases. This mainly applies to duplicate tags which are allowed. In the event that a tag already exists, the original tag is replaced.
- There are also no checks on the validity of permission names. Although valid android permissions are expected, nothing prevents unknowns.
- Enforcement decisions:
- All signatures used to sign an application are checked for policy according to signer tags. Only one of the signature policies has to pass however.
- In the event that none of the signature policies pass, or none even match, then a global package policy is sought. If found, this policy mediates the install.
- The default tag is consulted last if needed.
- A local package policy always overrides any parent policy.
- If none of the cases apply then the app is denied.
An edited form of an SEAndroid mac_permissions.xml file is as follows:
<?xml version="1.0" encoding="utf-8"?> <policy> <!-- Platform dev key in AOSP --> <signer signature="@PLATFORM" > <allow-all /> <seinfo value="platform" /> </signer> <!-- Media dev key in AOSP --> <signer signature="@MEDIA" > <allow-permission name="android.permission.ACCESS_ALL_DOWNLOADS" /> <allow-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> <allow-permission name="android.permission.WRITE_MEDIA_STORAGE" /> <allow-permission name="android.permission.WRITE_SETTINGS" /> <seinfo value="media" /> </signer> <!-- shared dev key in AOSP --> <signer signature="@SHARED" > <allow-permission name="android.permission.ACCESS_COARSE_LOCATION" /> <allow-permission name="com.android.voicemail.permission.ADD_VOICEMAIL" /> <seinfo value="shared" /> </signer> <!-- release dev key in AOSP --> <signer signature="@RELEASE" > <seinfo value="release" /> <deny-permission name="android.permission.BRICK" /> <deny-permission name="android.permission.READ_LOGS" /> <package name="com.android.browser" > <allow-permission name="android.permission.SET_WALLPAPER" /> <allow-permission name="android.permission.USE_CREDENTIALS"/> <allow-permission name="android.permission.WAKE_LOCK"/> <allow-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> <allow-permission name="android.permission.WRITE_SETTINGS" /> <allow-permission name="android.permission.WRITE_SYNC_SETTINGS" /> <seinfo value="release" /> </package> </signer> <!-- All other keys --> <default> <seinfo value="default" /> <deny-permission name="android.permission.ACCESS_COARSE_LOCATION" /> <deny-permission name="android.permission.ACCESS_FINE_LOCATION" /> <deny-permission name="android.permission.AUTHENTICATE_ACCOUNTS" /> <deny-permission name="android.permission.CALL_PHONE" /> <deny-permission name="android.permission.CAMERA" /> <deny-permission name="android.permission.READ_LOGS" /> <deny-permission name="android.permission.WRITE_EXTERNAL_STORAGE" /> </default> </policy>
Intent MMAC Configuration Files
There are two configuration files to support Intent MMAC, they are:
- intent_mac.xml - This defines the intents that will be allowed between each source and destination. The source and destination may be package names or <type name entries defined in the mmac_types.xml file (see Using Type or Package Names below on implementing these). There is also an optional <allow-all> section.
- mmac_types.xml - Contains <type name entries allowing source and destination entries defined in the intent_mac.xml file to manage intents on a package, signature and/or permissions basis.
intent_mac.xml File
The file supports two optional types of entry:
- <intent> filters that specify actions (intents) allowed between their source and destination, additional optional entries may also be added that refine the intent. The source and destination entries may be defined in the mmac_types.xml file.
- <allow-all> that will allow all intents from the source to destination entries.
All intent_mac.xml file entries are between <policy> tags:
<?xml version="1.0" encoding="utf-8"?> <policy> ...... </policy>
The build process supports additional device specific intent_mac.xml files as described in the Building the Policy section.
Intent Filter Entry
Each intent entry is as follows:
- <intent> start tag.
- <filter> start tag. The entries that follow would generally be obtained from the appropriate package manifest that describe the intent and its parameters.
- An <action name="" /> entry defining the intent action name.
- Zero or more <category name="" /> entries defining the intent category name.
- Zero or more <data scheme="" /> entries defining the intent scheme data specification.
- Zero or more <data mimeType="" /> entries defining the intent mime type data specification.
- </filter> end tag.
- One or more <allow entries that consist of the following:
- An optional rule name= entry that will be displayed in debug logs.
- Optional src= and dst= references for the allowed intents. These entries are generally <type name="" entries defined in the mmac_types.xml file, however they may also be package names, see the Using Type or Package Names section for further details. Note: It is recommended that both src= and dst= entries are specified. Not specifying either of them or the dst= will allow the intent to 'anywhere'. The only exception should be when source context matching is used.
- An optional srcctx= entry that will be matched against the source app process context.
- /> The allow end tag.
- <filter> start tag. The entries that follow would generally be obtained from the appropriate package manifest that describe the intent and its parameters.
- </intent> end tag.
Example entries are:
<?xml version="1.0" encoding="utf-8"?> <policy> <intent> <filter> <action name="android.intent.action.CALL_PRIVILEGED"/> <data scheme="tel"/> <data scheme="voicemail"/> </filter> <allow src="contacts_app" dst="telephony_app"/> </intent> <intent> <filter> <action name="android.intent.action.VIEW"/> <data mimeType="vnd.android.cursor.dir/calls" /> </filter> <allow src="telephony_app" dst="contacts_app"/> </intent> </policy>
allow-all Entry
An <allow-all> entry consists of:
- <allow-all> start tag.
- Zero of more <allow entries that consist of the following:
- An optional rule name= entry that will be displayed in debug logs.
- Optional src and dst references of the allowed intents. These entries are generally package names to allow all intents to flow between them, however they may be <type name="" entries defined in the mmac_types.xml file, see the Using Type or Package Names section for further details.
- An optional srcctx entry that will be matched against the source app process context.
- /> The allow end tag.
- Zero of more <allow entries that consist of the following:
- </allow-all> end tag.
An example <allow-all> entry:
<allow-all> <allow name="phone_to_sms" src="com.android.phone" dst="com.android.smspush"/> <allow name="shell" srcctx="u:r:shell:s0"/> <allow name="su" srcctx="u:r:su:s0"/> </allow-all>
Using Type or Package Names
The above <allow name= example src= and dst= entries shown are the actual package names. These entries may be implemented in the following ways:
1) Generate a new type entry for each package name in the mmac_types.xml file, for example:
<type name="com.android.phone"/> <type name="com.android.smspush"/>
- This would satisfy the <allow name="phone_to_sms" example entry given above.
2) Use existing type entries that already define the package name, for example the default mmac_types.xml file has the following entries:
<type name="wappush_app"> <signature value="@RELEASE"/> <package value="com.android.smspush"/> </type> <type name="telephony_app"> <signature value="@PLATFORM"/> <package value="com.android.phone"/> </type>
- The example <allow entry would then be defined as:
<allow name="phone_to_sms" src="telephony_app" dst="wappush_app"/>
3) Set the persist.mac_applyNameTypes permission to true, as this enables package names to be automatically be added as <type name= entries as the policy is loaded.
adb shell su 0 setprop persist.mac_applyNameTypes 1
mmac_types.xml File
The mmac_types.xml file contains the <type> entries that provide the source / destination references for the package and/or permissions rules used by the intent_mac.xml file. All entries are between <policy> tags:
<?xml version="1.0" encoding="utf-8"?> <policy> ...... </policy>
The build process supports additional device specific mmac_types.xml files as described in the Building the Policy section.
Each mmac_types.xml file entry is as follows:
- <type name="" > entry that defines the name that will be referenced by the intent_mac.xml file src="" and dst="" entries.
- Zero or more package value="" entries containing package names.
- Zero or more <signature value="" /> entries. These may be the key as extracted by setool (but it will need to be copied here from the setool output), or the "@.." format as shown in the example below, the signature will then be automatically generated as part of the build process by [[#insertkeys.py|insertkeys.py]} as described in Building the Policy section. It is recommended that a signature is always present.
- Zero or more permission value="" /> entries containing the allowed package permissions.
- </type> end tag.
Example entries are:
<?xml version="1.0" encoding="utf-8"?> <policy> <type name="telephony_app"> <signature value="@PLATFORM"/> <package value="com.android.phone"/> </type> <type name="video_perm"> <permission value="android.permission.CAMERA"/> <permission value="android.permission.RECORD_AUDIO"/> </type> </policy>
Content Provider MMAC Configuration File
The content_provider.xml file supports the following types of entry:
- Package <type> entries that describe source package parameters.
- Content <type> entries that describe target content provider parameters.
- <attribute> entries that assign a common name to multiple <type> entries.
- <allow-content> entries that define the source, target and permissions to allow access to content.
All entries are between <policy> tags:
<?xml version="1.0" encoding="utf-8"?> <policy> ...... </policy>
The build process supports additional device specific content_provider.xml files as described in the Building the Policy section.
Package <type> Entries
Each content_provider.xml file package type entry is as follows:
- <type name="" component="package" > entry. The name entry defines the name that will be referenced by the attribute <type> and/or <allow> source entry. The component entry specifies this as a package entry (other entries may be supported later).
- Zero or more <package value="" /> entries defining the package name.
- Zero or more <signature value="" /> entries. These may be the key as extracted by setool (but it will need to be copied here from the setool output), or the "@.." format as shown in the example below, the signature will then be automatically generated as part of the build process by insertkeys.py as described in Building the Policy section.
- Zero or more <permission value="" /> entries defining the permissions.
- </type> end tag.
When computing access to content the following precedence rules apply to package type entries:
- Signature defined over signature not defined.
- Package name defined over package name not defined.
- Permission set defined over permission set not defined.
There is no distinction between a stanza that has more signatures than another. They are considered of equal precedence.
Example entries are:
<?xml version="1.0" encoding="utf-8"?> <policy> <type name="platform" component="package"> <signature value="@PLATFORM"/> </type> <type name="shared" component="package"> <signature value="@SHARED"/> </type> <type name="release" component="package"> <signature value="@RELEASE"/> </type> <type name="media" component="package"> signature value="@MEDIA"/> </type> <type name="defualt_package" component="package"> </type> <type name="demo_resolver_package" component="package"> <package value="com.example.resolvecontent" /> <permission value="com.se4android.contentprovider.READ" /> <permission value="com.se4android.contentprovider.WRITE" /> </type> </policy>
Provider <type> Entries
Each content_provider.xml file provider type entry is as follows:
- <type name="" > entry. The name entry defines the name that will be referenced by the attribute <type> and/or <allow> destination entries.
- Zero or more <provider value="" /> entries defining the provider authority.
- Zero or more <package value="" /> entries defining the package name.
- Zero or more <signature value="" /> entries. These may be the key as extracted by setool (but it will need to be copied here from the setool output), or the "@.." format as shown in the example below, the signature will then be automatically generated as part of the build process by insertkeys.py as described in Building the Policy section. It is recommended that a signature is always present.
- Zero or more <export-read value="" /> entries defining the read protection level (protectionLevel= in manifest). These are defined as normal, dangerous, signature or signatureOrSystem).
- Zero or more <export-write value="" /> entries defining the write protection level (as export-read above).
- </type> end tag.
When computing access to content the following precedence rules apply to content type entries:
- Signature defined over signature not defined.
- Provider defined over provider not defined.
- Package name defined over package name not defined.
There is no distinction between a stanza that has more signatures than another. They are considered of equal precedence.
Example entries are:
<?xml version="1.0" encoding="utf-8"?> <policy> <type name="browser_exported_provider"> <signature value="@RELEASE"/> <provider value="com.android.browser"/> <provider value="browser"/> </type> <type name="browser_protected_provider"> <signature value="@RELEASE"/> <provider value="com.android.browser.home"/> <provider value="com.android.browser.snapshots"/> </type> <type name="platform_default_provider"> <signature value="@PLATFORM"/> </type> <type name="shared_default_provider"> <signature value="@SHARED"/> </type> <type name="media_default_provider"> <signature value="@MEDIA"/> </type> <type name="release_default_provider"> <signature value="@RELEASE"/> </type> <type name="default_provider"> </type> <type name="demo_provider"> <package value="com.se4android.contentprovider" /> <signature value="@RELEASE"/> <provider value="com.se4android.contentprovider.contentproviderdemo"/> <export-read value="normal" /> <export-write value="dangerous" /> </type> <policy>
Attribute Entries
The content_provider.xml file attribute entries consist of:
- <attributes> start tag.
- Zero or more <attribute name="" > entries. The name= entry defines the group name used to reference all the <type> entries. The name= may then be used in <allow> source= (for groups of package types) or destination= (for groups of content types) entries.
- Zero or more <type name="" /> entries. The name= entry refers to a package or content type entry.
- </attribute> end tag.
- Zero or more <attribute name="" > entries. The name= entry defines the group name used to reference all the <type> entries. The name= may then be used in <allow> source= (for groups of package types) or destination= (for groups of content types) entries.
- </attributes> end tag.
Example <attributes> entry:
<?xml version="1.0" encoding="utf-8"?> <policy> <attributes> <attribute name="all"> <type name="platform"/> <type name="release"/> <type name="shared"/> <type name="gapps"/> <type name="media"/> <type name="vpn"/> <type name="default"/> </attribute> <attribute name="trusted_apps"> <type name="platform"/> <type name="release"/> <type name="shared"/> <type name="gapps"/> <type name="media"/> </attribute> <attribute name="all_media_provider"> <type name="media_provider"/> <type name="drm_provider"/> </attribute> </attributes> </policy>
allow-content Entry
The content_provider.xml file allow content entries consist of:
- <allow-content> start tag.
- Zero of more <allow entries that consist of the following:
- A source="" reference to a package type entry.
- A destination="" reference to a content type entry.
- A permission="" entry stating that the source= reference may use (use), read (r), write (w) or read/write (rw) the destination= content provider. Each permission is separated by a semi-colon (;). The use permission is required to obtain a handle to the content provider, but does not provide read or write capability. Read, Write, or Read-Write imply the use permission.
- /> The allow end tag.
- Zero of more <allow entries that consist of the following:
- </allow-content> end tag.
Example <allow-content> entry:
<?xml version="1.0" encoding="utf-8"?> <policy> <allow-content> <allow source="all" destination="settings_provider" permission="use;r"/> <allow source="trusted_apps" destination="all_contacts_provider" permission="use;r"/> <allow source="platform" destination="media_provider" permission="use;rw"/> <allow source="release" destination="mms_sms_provider" permission="use;rw"/> <allow source="release" destination="browser_exported_provider" permission="use;rw"/> <allow source="release" destination="all_calendar_provider" permission="use;r"/> <allow source="release" destination="all_email_provider" permission="use;r"/> <allow source="platform" destination="all_telephony_provider" permission="use;r"/> <allow source="release" destination="search_provider" permission="use;r"/> <allow source="release" destination="media_provider" permission="use;rw"/> <allow source="shared" destination="dictionary_provider" permission="use;r"/> <allow source="shared" destination="email_attach_provider" permission="use;r"/> <allow source="demo_resolver_package" destination="demo_provider" permission="use;rw"/> <allow source="demo_resolver_package" destination="settings_provider" permission="use;r"/> </allow-content> </policy>
Revoke Permissions MMAC Configuration File
The revoke_permissions.xml file is used to configure revoked permissions. The build process does not currently support additional files.
All entries are between <revoke-policy> tags:
<?xml version="1.0" encoding="utf-8"?> <revoke-policy> ...... </revoke-policy>
The revoke_permissions.xml file entries are as follows:
- <package name="" > entry. The name= refers to the package name.
- One or more <revoke-permission name="" /> entries. The name= refers to the permission to be denied.
- </package> end tag.
An example entry is:
<?xml version="1.0" encoding="utf-8"?> <revoke-policy> <package name="com.example.runisolatedservice "> <revoke-permission name="com.se4android.isolatedservice.permission.DEADLY_ACTIVITY"/> </package> </revoke-policy>
Policy Build Tools
This section covers the policy build tools located at external/sepolicy/tools. They are checkfc, checkseapp and insertkeys.py. There is also setool that is not used as part of the build process but generates mac_permissions.xml entries from packages.
checkfc
The checkfc utility is used during the build process to validate the file_contexts and property_contexts files against policy. If validation fails checkfc will exit with an error.
checkfc -h will give the following output:
usage: checkfc [OPTIONS] sepolicy context_file Parses a context file and checks for syntax errors. The context_file is assumed to be a file_contexts file unless explicitly switched by an option. OPTIONS: -p : context file represents a property_context file.
Example validating file_contexts file:
checkfc out/target/product/generic/root/sepolicy out/target/product/generic/root/file_contexts
Example validating property_contexts file:
checkfc -p out/target/product/generic/root/sepolicy out/target/product/generic/root/property_contexts
checkseapp
The checkseapp utility is used during the build process to validate the seapp_contexts file against policy. If validation fails checkseapp will exit with an error. checkseapp also consolidates matching entries and outputs the valid file stripped of comments.
checkseapp -h will give the following output:
checkseapp [options] <input file> Processes an seapp_contexts file specified by argument <input file> (default stdin) and allows later declarations to override previous ones on a match. Options: -h - print this help message -v - enable verbose debugging informations -p policy file - specify policy file for strict checking of output selectors -o output file - specify output file, default is stdout
An example command with output to stdout is:
checkseapp -p out/target/product/generic/root/sepolicy out/target/product/generic/root/seapp_contexts isSystemServer=true domain=system user=system domain=system_app type=system_data_file user=bluetooth domain=bluetooth type=bluetooth_data_file user=nfc domain=nfc type=nfc_data_file user=radio domain=radio type=radio_data_file user=_app domain=untrusted_app type=app_data_file levelFrom=app user=_app seinfo=platform domain=platform_app type=platform_app_data_file user=_app seinfo=shared domain=shared_app type=platform_app_data_file user=_app seinfo=media domain=media_app type=platform_app_data_file user=_app seinfo=release domain=release_app type=platform_app_data_file user=_isolated domain=isolated_app
insertkeys.py
The insertkeys.py utility is used during the build process to insert signing keys into multiple mac_permissions.xml, mmac_types.xml and content_provider.xml files. The keys are obtained from pem files and the entries to be replaced start with an @ followed by a keyword. The external/sepolicy/keys.conf file contains corresponding entries that allow mapping of pem files to signatures as discussed in the keys.conf section.
Note that pem files are base64 encoded however the Android Package Manager Service uses base16 encodings. Therefore insertkeys.py and setool will generate base16 encodings for the mac_permissions.xml and mmac_types.xml files.
insertkeys.py will also strip the files of comments and whitespace to preserve space on the system.img. To view the output file in a more human friendly format the tidy or xmllint command can be used.
insertkeys.py -h will give the following output for 4.3 (4.2 does not have the -d option):
Usage: insertkeys.py [options] CONFIG_FILE MAC_PERMISSIONS_FILE [MAC_PERMISSIONS_FILE...] This tool allows one to configure an automatic inclusion of signing keys into the mac_permission.xml file(s) from the pem files. If multiple mac_permission.xml files are included then they are unioned to produce a final version. Options: --version show program's version number and exit -h, --help show this help message and exit -v, --verbose Print internal operations to stdout -o FILE, --output=FILE Specify an output file, default is stdout -c DIR, --cwd=DIR Specify a root (CWD) directory to run this from, itchdirs' AFTER loading the config file -t TARGET_BUILD_VARIANT, --target-build-variant=TARGET_BUILD_VARIANT Specify the TARGET_BUILD_VARIANT, defaults to eng -d KEY_DIRECTORY, --key-directory Specify a parent directory for keys
An example command that takes two mac_permission.xml files inserts the signatures and concatenates them into a single file is:
insertkeys.py -o demo/unioned_mac_permissions.xml external/sepolicy/keys.conf \ external/sepolicy/mac_permissions.xml demo/mac_permissions.xml
keys.conf
The keys.conf file is used by insertkeys.py for mapping the "@..." tags in mac_permissions.xml and mmac_types.xml signature entries with public keys found in pem files. The configuration file can be used in BOARD_SEPOLICY_UNION and BOARD_SEPOLICY_REPLACE variables and is processed via m4 macros.
insertkeys.py allows for mapping any string contained in TARGET_BUILD_VARIANT with a specific path to a pem file. Typically TARGET_BUILD_VARIANT is either user, eng or userdebug. Additionally "ALL" may be specified to map a path to any string specified in TARGET_BUILD_VARIANT. All tags are matched verbatim and all options are matched lowercase. The options are "tolowered" automatically for the user, it is convention to specify tags and options in all uppercase and tags start with @.
An example keys.conf file for AOSP 4.3 is as follows (note that the path is now supplied by the -d option when calling insertkeys.py in the external/sepolicy/Android.mk file):
# # Maps an arbitrary tag [TAGNAME] with the string contents found in # TARGET_BUILD_VARAINT. Common convention is to start TAGNAME with an @ and # name it after the base file name of the pem file. # # Each tag (section) then allows one to specify any string found in # TARGET_BUILD_VARIANT. Typically this is user, eng, and userdebug. Another # option is to use ALL which will match ANY TARGET_BUILD_VARAINT string. # [@PLATFORM] ALL : platform.x509.pem [@MEDIA] ALL : media.x509.pem [@SHARED] ALL : shared.x509.pem # Example of ALL TARGET_BUILD_VARIANTS [@RELEASE] ENG : testkey.x509.pem USER : testkey.x509.pem USERDEBUG : testkey.x509.pem
The following is an example entry that will use a device specific key for release 4.3 during the build process:
[@NET_APPS] ALL : $ANDROID_BUILD_TOP/device/demo_vendor/demo_device/security/net_apps.x509.pem
Should the build fail because of keys.conf entries, check that the following patch is installed:
https://android-review.googlesource.com/#/c/63370/
If using 4.2, then a device specific example entry would be:
[@NET_APPS] ALL : device/demo_vendor/demo_device/security/net_apps.x509.pem
buildsebundle
The following text has been extracted from an email that describes this new 4.3 feature: New code has been released that allow for policy reloading via Android's new UpdateConfig mechanism. Android 4.3 has brought a new set of OTA update hooks for various policy files including some of the SELinux ones. This is a way forward with reloadable policy support and as such have updated the SEAdmin project (master and seandroid-4.3 branches) with a new but limited reload option as well as updated the sepolicy project (seandroid and seandroid-4.3 branches) with new tooling. Some things to note:
- In order for SEAdmin to reload policy there is a required format imposed by the backed ConfigUpdate code. A new signed policy 'bundle' and metadata file are required; the bundle being a packed version of various selinux policy files. Because of this new format, a new tool called buildsebundle has been developed that will help with the construction of such files. It is not built as standard, therefore need to 'make buildsebundle' first and then see the help menu below along with an example.
- buildsebundle actually outputs a zip file containing the packed bundle and metadata file. The zip file isn't a direct requirement for the ConfigUpdate code but merely serves as a convenient packaging format to deliver both files to the device. This zip file will need to be pushed to /sdcard for SEAdmin to reload it.
- There is a requirement that the resulting bundle be signed for integrity purposes. The buildsebundle tool will help with this but a few caveats are in order. The backend code on the phone requires that an approved OTA cert already be loaded into the Settings secure database to verify the incoming reload request. This means that the cert on the phone must match the key fed the buildsebundle tool. SEAdmin has been changed to insert a key by first reading the entries in otacerts.zip on boot. The otacerts.zip file will include the correct testkey/releasekey when building the system image.
- There is no support for reloading mac_permissions.xml via this new reload mechanism. This is a limitation of the back end code which only supports reloading file_contexts, sepolicy, property_contexts and seapp_contexts policy files. The previous option for reloading mac_permissions.xml remains supported in the SEAdmin app however. The project will also continue to support the SEAdmin app as the ConfigUpdate code doesn't presently offer the abilities to switch to enforcing mode or toggle booleans.
- AOSP code for the new update mechanism can be found at: frameworks/base/services/java/com/android/server/updates/* .
- Since the ConfigUpdate code seems to still be under development, the SEAndroid project will most likely move in-step with that code in order to bring ideas together whenever possible. So, updates to both the SEAdmin and sepolicy tooling are possible in the future.
buildsebundle -h will give the following output:
usage: buildsebundle -k <private key.pk8> [-v <version>] [-r <previous hash>] [-h] -- <file_contexts> <property_contexts> <sepolicy> <seapp_contexts> This script builds a selinux policy bundle and supporting metadata file capable of being loaded via the ConfigUpdate mechanism. It takes a pkcs8 DER encoded RSA private key that is then used to sign the bundle. For AOSP development you'll typically want to use the key from the source tree at build/target/product/security/testkey.pk8. If building your own cert you should probably use at least a key size of 1024 or greater. The bundle requires that seapp_contexts, file_contexts, property_contexts and sepolicy files all be included and with those exact basenames. The built bundle will be written to selinux_bundle.zip which will include the signature metadata file of the bundle. OPTIONS: -h Show this message. -v Version of the built bundle. Defaults to 1. -r Sha512 hash of the bundle to replace. Defaults to 'NONE'.
The following example (with policy files in cwd will produce an selinux_bundle.zip file containing two files update_bundle and update_bundle_metadata:
buildsebundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -- file_contexts \ property_contexts sepolicy seapp_contexts
setool
The setool utility is not used during the build process and is intended only to produce 'starter' entries for the mac_permissions.xml file. It is not supplied in AOSP.
The entries produced will generally have to be modified because currently:
- If multiple packages are given each with the same signature, a separate entry will be generated for each package. If added to the mac_permissions.xml file only the first entry will be used by the Install MMAC process (therefore the packages need to be consolidated into on entry).
- setool will generate (--build) entries for third party apps, however it should not as they will be ignored by the Install MMAC.
- setool will check (--policy) third party apps against the full mac_permissions.xml policy, however it should not, it should only check them against the <default> entries only.
Having said that, setool is still useful as it will generate the signature entries and extract the permissions.
setool --help will give the following output:
Usage: setool [flags] <--build|--policy> <apks> Tool to help build and verify MMAC install policies. apks List of apks to analyze, space separated. All supplied apks must be absolute paths or relative to --apkdir (which defaults to the current directory). --build Generate an MMAC style policy stanza. The resulting stanza can then be used as an entry in the mac_permissions.xml file. whitelist Policy entry that contains a white listing of all permissions. The stanza will contain the app's package tag within its signer tag. keys Print a valid signer tag which contains the hex encoded X.509 cert of the app. --policy Determine if supplied apks pass the supplied policy. Flags: --help Prints this message and exits. --apkdir Directory to search for supplied apks (default to current directory). --verbose Increase the amount of debug statements. --outfile Dump all output to the given file (defaults to stdout). --seinfo Create an seinfo tag for all generated policy stanzas.
The following are examples of using setool:
setool --build whitelist RunIsolatedService.apk > demo/ mac_permissions.xml
The output will be:
<signer signature="- key will be here -"> <package name="com.example.runisolatedservice"> <allow-permission name="com.se4android.isolatedservice.permission.DEADLY_ACTIVITY" /> </package> </signer>
uid To username Utility
This utility will take an Android uid and convert it to a username. The code is a modified version from bionic/libc/bionic/stubbs.cpp that converts an Android uid to username.
To compile this assumes that the environment variable $PREFIX is set to the Android project directory. This is to allow the header file to be located:
cc -std=gnu99 uid_to_username.c -o uid_to_username -include \ $PREFIX/system/core/include/private/android_filesystem_config.h
#include <stdio.h> #include <stdlib.h> #define CAT_MAPPING_MAX_ID (0x1<<16) int main(int argc, char **argv) { uid_t uid; if (argc != 2) { printf("Converts an Android uid to username\n"); printf("usage: %s uid\n\n", argv[0]); exit(1); } uid = atoi(argv[1]); uid_t appid = uid % AID_USER; uid_t userid = uid / AID_USER; if (appid >= CAT_MAPPING_MAX_ID || userid >= CAT_MAPPING_MAX_ID) { printf("Failed as the maximum uid that can be mapped has been exceeded.\n"); exit(0); } printf("appid: %u userid: %u\nusername: ", appid, userid); if (appid >= AID_ISOLATED_START) { printf("u%u_i%u\n", userid, appid - AID_ISOLATED_START); } else if (userid == 0 && appid >= AID_SHARED_GID_START) { printf("all_a%u\n", appid - AID_SHARED_GID_START); } else if (appid < AID_APP) { for (size_t n = 0; n < android_id_count; n++) { if (android_ids[n].aid == appid) { printf("u%u_%s\n", userid, android_ids[n].name); printf("Note that only the name \"%s\" is listed in 'ps' etc.\n", android_ids[n].name); exit(0); } } printf("Failed - invalid uid\n"); } else { printf("u%u_a%u\n", userid, appid - AID_APP); } exit(0); }