Difference between revisions of "NB SEforAndroid 2"

From SELinux Wiki
Jump to: navigation, search
(property_contexts File)
 
(12 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Policy File Configuration Details =
+
= Policy Configuration File Formats =
 +
This section details the Android policy configuration file formats with worked examples.
  
This section details the specific SE for Android policy configuration files (i.e. those not used by 'standard' Linux based SELinux) as they were in April '13. Where those files are used to compute contexts using the SE for Android libselinux functions, those functions are also described with examples.
+
The following files are described:
 +
*  <tt>file_contexts
 +
*  seapp_contexts
 +
*  service_contexts
 +
*  property_contexts
 +
*  mac_permissions.xml
 +
*  eops.xml
 +
*  ifw.xml</tt>
  
As this project is continually being enhanced, it is recommended that the official project wiki is checked for the latest enhancements at [[SEforAndroid | SEforAndroid]]
+
== file_contexts  ==
 +
This file is used to associate default contexts to files for file systems that support extended file attributes. It is used by the file labeling commands such as <tt>restorecon</tt>.
  
 +
The [[NB_SEforAndroid_1#Checking File Labels | Checking File Labels]] section describes how changes in this file are detected.
  
== SELinux MAC Files ==
+
The build process supports additional <tt>file_contexts</tt> files allowing devices to specify their entries as described in the [[NB_SEforAndroid_1#Processing Device Policy | Processing Device Policy]] section.
=== 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:
+
: <tt>selinux_android_setcontext</tt> - Computes process security contexts.
+
: <tt>selinux_android_setfilecon2</tt> - Computes file/directory security contexts.
+
<tt>selinux_android_seapp_context_reload</tt> will also reload this file.
+
  
The build process supports additional <tt>seapp_contexts</tt> files to allow devices to specify their specific entries as described in the [[NB_SEforAndroid_1#Building the Policy| Building the Policy]] section.
+
Each line within the file consists of the following:
 +
<pre>
 +
pathname_regexp [file_type] security_context
 +
</pre>
 +
 
 +
'''Where:'''
 +
{| border="1"
 +
| <tt>pathname_regexp</tt>
 +
| An entry that defines the pathname that may be in the form of a regular expression (see the example file_contexts file below).
 +
 
 +
|-
 +
| <tt>file_type</tt>
 +
| One of the following optional file_type entries (note if blank means "match all file types"):
 +
: '<tt>-b</tt>' - Block Device  '<tt>-c</tt>' - Character Device
 +
: '<tt>-d</tt>' - Directory      '<tt>-p</tt>' - Named Pipe (FIFO)
 +
: '<tt>-l</tt>' - Symbolic Link  '<tt>-s</tt>' - Socket File
 +
: '<tt>--</tt>' - Ordinary file
 +
 
 +
This entry equates to the file mode and also the file related object class (e.g. <tt>S_IFSOCK</tt> = <tt>sock_file</tt> class).
 +
 
 +
|-
 +
| security_context
 +
| This entry can be either:
 +
* The security context that will be assigned to the file.
 +
* A value of <tt><nowiki><<none>></nowiki></tt> that states matching files should not be re-labeled.
 +
 
 +
 
 +
|}
 +
 
 +
Example entries:
 +
<pre>
 +
###########################################
 +
# Root
 +
/u:object_r:rootfs:s0
 +
 
 +
# Data files
 +
/adb_keys      u:object_r:adb_keys_file:s0
 +
/default\.prop  u:object_r:rootfs:s0
 +
/fstab\..*      u:object_r:rootfs:s0
 +
/init\..*      u:object_r:rootfs:s0
 +
/res(/.*)?      u:object_r:rootfs:s0
 +
/ueventd\..*    u:object_r:rootfs:s0
 +
...
 +
##########################
 +
# Devices
 +
#
 +
/dev(/.*)?        u:object_r:device:s0
 +
/dev/akm8973.*    u:object_r:sensors_device:s0
 +
/dev/accelerometer  u:object_r:sensors_device:s0
 +
/dev/adf[0-9]*      u:object_r:graphics_device:s0
 +
/dev/adf-interface[0-9]*\.[0-9]*      u:object_r:graphics_device:s0
 +
/dev/adf-overlay-engine[0-9]*\.[0-9]*  u:object_r:graphics_device:s0
 +
...
 +
/dev/socket/adbd        u:object_r:adbd_socket:s0
 +
/dev/socket/dnsproxyd  u:object_r:dnsproxyd_socket:s0
 +
/dev/socket/dumpstate  u:object_r:dumpstate_socket:s0
 +
...
 +
#############################
 +
# System files
 +
#
 +
/system(/.*)?      u:object_r:system_file:s0
 +
/system/bin/sh  --  u:object_r:shell_exec:s0
 +
/system/bin/run-as  --  u:object_r:runas_exec:s0
 +
 
 +
#############################
 +
# asec containers
 +
/mnt/asec(/.*)?          u:object_r:asec_apk_file:s0
 +
/mnt/asec/[^/]+/res\.zip  u:object_r:asec_public_file:s0
 +
/mnt/asec/[^/]+/lib(/.*)? u:object_r:asec_public_file:s0
 +
/data/app-asec(/.*)?      u:object_r:asec_image_file:s0
 +
</pre>
 +
 
 +
These are example entries from <tt>device/asus/flo/sepolicy/file_contexts</tt>, note the '<tt>'''by-name'''</tt>' entry. This is resolved by <tt>ueventd</tt> as explained in the following commit:
 +
: [https://android.googlesource.com/platform/system/core/+/b0ab94b7d5a888f0b6920b156e5c6a075fa0741a https://android.googlesource.com/platform/system/core/][https://android.googlesource.com/platform/system/core/+/b0ab94b7d5a888f0b6920b156e5c6a075fa0741a +/b0ab94b7d5a888f0b6920b156e5c6a075fa0741a]
 +
<pre>
 +
# efs block labeling
 +
/dev/block/platform/msm_sdcc\.1/by-name/m9kefs[123c] u:object_r:efs_block_device:s0
 +
# Root block labeling
 +
/dev/block/mmcblk0 u:object_r:root_block_device:s0
 +
# modemst1, modemst2, fsg, ssd labeling
 +
/dev/block/platform/msm_sdcc\.1/by-name/modemst[12] u:object_r:modem_block_device:s0
 +
/dev/block/platform/msm_sdcc\.1/by-name/fsg        u:object_r:modem_block_device:s0
 +
/dev/block/platform/msm_sdcc\.1/by-name/ssd        u:object_r:modem_block_device:s0
 +
</pre>
 +
 
 +
It is also worth noting that the '<tt>'''by-name'''</tt>' (or '<tt>'''by-num'''</tt>') entry can exist in fstab files as shown in this example taken from <tt>device/asus/flo/fstab.flo</tt>:
 +
<pre>
 +
/dev/block/platform/msm_sdcc.1/by-name/system  /system ext4 ro,barrier=1 wait
 +
/dev/block/platform/msm_sdcc.1/by-name/userdata /data  ext4
 +
</pre>
 +
 
 +
== seapp_contexts  ==
 +
This file is loaded and sorted into memory using the precedence rules explained below on first use by of one of the following Android <tt>libselinux</tt> functions:
 +
* <tt>selinux_android_setcontext</tt> - Computes process security contexts.
 +
* <tt>selinux_android_setfilecon</tt> - Computes file/directory security contexts.
 +
 
 +
The [[NB_SEforAndroid_1#Checking File Labels | Checking File Labels]] section describes how changes in this file are detected.
 +
 
 +
The build process supports additional <tt>seapp_contexts</tt> files allowing devices to specify their entries as described in the [[NB_SEforAndroid_1#Processing Device Policy | Processing Device Policy]] section.
  
 
The following sections will show:
 
The following sections will show:
 
# The default <tt>external/sepolicy/seapp_contexts</tt> file entries.
 
# The default <tt>external/sepolicy/seapp_contexts</tt> file entries.
 
# A description of the <tt>seapp_contexts</tt> entries and their usage.
 
# A description of the <tt>seapp_contexts</tt> entries and their usage.
# A brief description of how a context is computed using either the <tt>selinux_android_setcontext</tt> or <tt>selinux_android_ setfilecon2</tt> function using the <tt>seapp_contexts</tt> file entries.
+
# A brief description of how a context is computed using either the <tt>selinux_android_setcontext</tt> or <tt>selinux_android_ setfilecon</tt> function using the <tt>seapp_contexts</tt> file entries.
 
# Examples of computed domain and directory contexts for various apps.
 
# Examples of computed domain and directory contexts for various apps.
  
==== Default Entries ====
+
=== Default Entries ===
The default <tt>external/sepolicy/seapp_contexts</tt> file contains the following entries:
+
The default Android <tt>external/sepolicy/seapp_contexts</tt> file contains the following entries:
 
<pre>
 
<pre>
isSystemServer=true domain=system
+
isSystemServer=true domain=system_server
user=system domain=system_app type=system_data_file
+
user=system domain=system_app type=system_app_data_file
 
user=bluetooth domain=bluetooth type=bluetooth_data_file
 
user=bluetooth domain=bluetooth type=bluetooth_data_file
 
user=nfc domain=nfc type=nfc_data_file
 
user=nfc domain=nfc type=nfc_data_file
 
user=radio domain=radio type=radio_data_file
 
user=radio domain=radio type=radio_data_file
user=_app domain=untrusted_app type=app_data_file levelFrom=app
+
user=shared_relro domain=shared_relro
user=_app seinfo=platform domain=platform_app type=platform_app_data_file
+
user=shell domain=shell type=shell_data_file
user=_app seinfo=shared domain=shared_app type=platform_app_data_file
+
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=media domain=media_app type=platform_app_data_file
+
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app seinfo=release domain=release_app type=platform_app_data_file
+
user=_app domain=untrusted_app type=app_data_file levelFrom=user
user=_isolated domain=isolated_app
+
 
</pre>
 
</pre>
  
==== Entry Definitions ====
+
=== 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:
 
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 <tt>seapp_contexts</tt> file:  
 
Input selectors from <tt>seapp_contexts</tt> file:  
: isSystemServer (boolean)
+
: <tt>isSystemServer (boolean)</tt>
 +
: <tt>isOwner (boolean)</tt>
 
: <tt>user (string)</tt>
 
: <tt>user (string)</tt>
 
: <tt>seinfo (string)</tt>
 
: <tt>seinfo (string)</tt>
 
: <tt>name (string)</tt> - A package name e.g. <tt>com.example.demo</tt>
 
: <tt>name (string)</tt> - A package name e.g. <tt>com.example.demo</tt>
: <tt>sebool (string)</tt> - The boolean must be ‘active’ (enabled/true)
+
: <tt>path (string)</tt> - A path name (added to ensure correct labeling of some files).
<tt>isSystemServer=true</tt> can only be used once.
+
An unspecified <tt>isSystemServer</tt> defaults to false.
+
  
An unspecified string selector will match any value.
+
Notes:
 
+
: <tt>isSystemServer=true</tt> can only be used once.
A <tt>user</tt> string selector that ends in <tt><nowiki>*</nowiki></tt> will perform a prefix match.
+
: An unspecified <tt>isSystemServer</tt> defaults to false.
 
+
: <tt>isOwner=true</tt> will only match for owner/primary user.
<tt>user=_app</tt> will match any regular app UID.
+
: <tt>isOwner=false</tt> will only match for secondary users.
 
+
: If unspecified, the entry can match either case.
<tt>user=_isolated</tt> will match any isolated service UID.
+
: An unspecified string selector will match any value.
 
+
: A <tt>user</tt> string selector that ends in <tt><nowiki>*</nowiki></tt> will perform a prefix match.
All specified input selectors in an entry must match (i.e. logical AND).
+
: <tt>user=_app</tt> will match any regular app UID.
 
+
: <tt>user=_isolated</tt> will match any isolated service UID.
Matching is case-insensitive.
+
: All specified input selectors in an entry must match (i.e. logical AND).
 +
: Matching is case-insensitive.
  
 
Precedence rules:
 
Precedence rules:
 
: 1) <tt>isSystemServer=true</tt> before <tt>isSystemServer=false</tt>.
 
: 1) <tt>isSystemServer=true</tt> before <tt>isSystemServer=false</tt>.
: 2) Specified <tt>user= string</tt> before unspecified <tt>user= string</tt>.
+
: 2) Specified <tt>isOwner=</tt> before unspecified <tt>isOwner=boolean</tt>.
: 3) Fixed <tt>user= string</tt> before <tt>user= prefix</tt> (i.e. ending in <tt><nowiki>*</nowiki></tt>).
+
: 3) Specified <tt>user= string</tt> before unspecified <tt>user= string</tt>.
: 4) Longer <tt>user= prefix</tt> before shorter <tt>user= prefix</tt>.  
+
: 4) Fixed <tt>user= string</tt> before <tt>user= prefix</tt> (i.e. ending in <tt><nowiki>*</nowiki></tt>).
: 5) Specified <tt>seinfo= string</tt> before unspecified <tt>seinfo= string</tt>.
+
: 5) Longer <tt>user= prefix</tt> before shorter <tt>user= prefix</tt>.  
: 6) Specified <tt>name= string</tt> before unspecified <tt>name= string</tt>.
+
: 6) Specified <tt>seinfo= string</tt> before unspecified <tt>seinfo= string</tt>.
: 7) Specified <tt>sebool= string</tt> before unspecified <tt>sebool= string</tt>.
+
: 7) Specified <tt>name= string</tt> before unspecified <tt>name= string</tt>.
 +
: 8) Specified <tt>path= string</tt> before unspecified <tt>path= string</tt>.
 +
 
 
Outputs:
 
Outputs:
 
: <tt>domain (string)</tt> - The <tt>type</tt> component of a process context.
 
: <tt>domain (string)</tt> - The <tt>type</tt> component of a process context.
Line 74: Line 178:
 
: <tt>levelFrom</tt> (<tt>string</tt><nowiki>; one of </nowiki><tt>none</tt>, <tt>all</tt>, <tt>app</tt>, or <tt>user</tt>) - A level that will be automatically computed based on the parameter.
 
: <tt>levelFrom</tt> (<tt>string</tt><nowiki>; one of </nowiki><tt>none</tt>, <tt>all</tt>, <tt>app</tt>, or <tt>user</tt>) - A level that will be automatically computed based on the parameter.
 
: <tt>level (string)</tt> - A predefined level (e.g. <tt>s0:c1022.c1023</tt>)
 
: <tt>level (string)</tt> - A predefined level (e.g. <tt>s0:c1022.c1023</tt>)
Only entries that specify <tt>domain=</tt> will be used for app process labeling.
 
  
Only entries that specify <tt>type=</tt> will be used for app directory labeling.
+
Notes:
 +
: Only entries that specify <tt>domain=</tt> will be used for app process labeling.
 +
: Only entries that specify <tt>type=</tt> will be used for app directory labeling.
 +
: <tt>levelFrom=user</tt> is only supported for <tt>_app</tt> or <tt>_isolated</tt> UIDs.
 +
: <tt>levelFrom=app</tt> or <tt>levelFrom=all</tt> is only supported for <tt>_app</tt> UIDs.
 +
: <tt>level</tt> may be used to specify a fixed level for any UID.  
  
<tt>levelFrom=user</tt> is only supported for <tt>_app</tt> or <tt>_isolated</tt> UIDs.
+
=== Computing a Context ===
 +
This section explains the process to compute a context using parameters supplied by the <tt>selinux_android_setcontext</tt>, <tt>selinux_android_setfilecon</tt>,<tt> selinux_android_restorecon</tt> and<tt> selinux_android_restorecon_pkgdir</tt> functions plus the precedence sorted contents of the <tt>seapp_contexts</tt> file, some examples are then shown.
  
<tt>levelFrom=app</tt> or <tt>levelFrom=all</tt> is only supported for <tt>_app</tt> UIDs.
+
The context is computed first by converting the <tt>uid</tt> parameter to a string that is used to match the <tt>user</tt> component in the <tt>seapp_contexts</tt> entry as follows:
 +
# If an Android system service, the <tt>uid</tt> parameter is converted to a <tt>username</tt> string via an internal Android table (e.g. "radio", "system").
 +
# If an isolated service the <tt>_isolated</tt> string is used as the <tt>username</tt>.
 +
# For any other app or service <tt>_app</tt> string is used as the <tt>username</tt>.
  
<tt>level</tt> may be used to specify a fixed level for any UID.
+
Then cycling through each precedence sorted <tt>seapp_contexts</tt> entry, check each component as follows until a match is found or generate an error log entry:
  
==== Computing a Process Context ====
+
* The <tt>isSystemServer</tt> component is matched against the <tt>isSystemServer</tt> parameter. If a match or <tt>isSystemServer</tt> not present check remaining components, else skip entry.
To compute an app process context the <tt>selinux_android_setcontext</tt> function is called that will use the parameters passed, plus the contents of the <tt>seapp_contexts</tt> file. The function parameters are:
+
* The <tt>isOwner</tt> boolean determines whether the remaining components should be checked or skip this entry. The rules are:
<pre>
+
** If <tt>isOwner</tt> not present then check remaining components.
#include <selinux/android.h>
+
** If set <tt>true</tt> and the <tt>uid</tt> computes to the owner or primary user then check remaining components, else skip this entry.
int selinux_android_setcontext(uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname);
+
** If set <tt>false</tt> and the <tt>uid</tt> computes to a secondary user then check remaining components, else skip this entry.
</pre>
+
* The computed <tt>username</tt> is matched against the <tt>user</tt> component. If a match or <tt>user</tt> not present check remaining components, else skip entry.
 +
* The <tt>seinfo</tt> component is matched against the <tt>seinfo</tt> parameter. If a match or <tt>seinfo</tt> not present check remaining components, else skip entry.
 +
* The <tt>name</tt> component is matched against the <tt>pkgname</tt> parameter. If a match or <tt>name</tt> not present check remaining components, else skip entry.
 +
* The <tt>path</tt> component is matched against a computed path of a file having its context restored via one of the restorecon functions. If a match or <tt>path</tt> not present check remaining components, else skip entry.
 +
* The <tt>domain</tt> component is used to set the process context for the <tt>selinux_android_setcontext</tt> function and must match a type declared in the policy. If <tt>domain</tt> not present skip this entry.
 +
* The <tt>type</tt> component is used to set the file context for the <tt>selinux_android_setfilecon</tt> function and must match a type declared in the policy. If <tt>type</tt> not present skip this entry.
 +
* The <tt>levelFrom</tt> and <tt>level</tt> components if present will be used to determine the <tt>level</tt> component of the security context as follows:
 +
** if <tt>levelFrom=none</tt> then use current level.
 +
** else if <tt>levelFrom=app</tt> then compute a category pair based on a derived app id with a starting base of <tt>c512,c768</tt> base.
 +
** else if <tt>levelFrom=user</tt> then compute a category pair based on a derived user id with a starting base of <tt>c0,c256</tt> base.
 +
** else if <tt>levelFrom=all</tt> then compute a category pair based on a derived app id with a starting base of <tt>c512,c768</tt> base, and also compute another category pair based on a derived user id with a starting base of <tt>c0,c256</tt> base.
 +
** else if <tt>level</tt> has a value use this as the context level.
  
The context is then computed using the information as follows:
+
The overall objective is that the computed levels should never be the same for different apps, users, or a combination of both. By encoding each ID as a category pair, up to 2^16 app IDs and up to 2^16 user IDs within the 1024 categories can be represented, including the <tt>levelFrom=all</tt> or mixed usage of <tt>levelFrom=app</tt> and <tt>levelFrom=user</tt>.
: The <tt>uid</tt> is converted to a string that is then used to match the <tt>user=</tt> entries in the <tt>seapp_contexts</tt> file as follows:
+
:: If an Android system service the <tt>uid</tt> is converted to a string via an internal Android table (e.g. "radio", "system").
+
:: If an isolated service the <tt>_isolated</tt> string is used.
+
:: For any other app or service the <tt>_app</tt> is used.
+
: The <tt>isSystemServer</tt> value must match that set in the running system and be true or false. It will be matched against the <tt>isSystemServer=</tt> entries in the <tt>seapp_contexts</tt> file.
+
: <tt>seinfo</tt> may be <tt>NULL</tt> or that obtained from the <tt>mac_permissions.xml</tt> file. It will be matched against the <tt>seinfo=</tt> entries in the <tt>seapp_contexts</tt> file.
+
: <tt>pkgname</tt> may be <tt>NULL</tt> or that obtained from the Android package. It will be matched against the <tt>name=</tt> entries in the <tt>seapp_contexts</tt> file.
+
: The remaining <tt>seapp_contexts</tt> entries will be used as follows:
+
:: The <tt>sebool=</tt> parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
+
:: The <tt>levelFrom=</tt> and <tt>level=</tt> parameters if present will be used to determine the <tt>level</tt> component of the security context.
+
:: The <tt>domain=</tt> is used to set the process context and must match a context in the policy. Determines the <tt>type</tt> component of the security context.
+
  
If a context is computed, it is validated against policy and if correct <tt>'''setcon'''(3)</tt> will then be used to set the process context.
+
If a valid entry is found, then:
 +
# If a context for the <tt>selinux_android_setcontext</tt> function has been computed, it is validated against policy, if correct <tt>'''setcon'''(3)</tt> is used to set the process context.
 +
# If a context for <tt>selinux_android_setfilecon</tt>, <tt>selinux_android_restorecon</tt> or<tt> selinux_android_restorecon_pkgdir</tt> functions have been computed, it is validated against policy, if correct <tt>'''setfilecon'''(3)</tt> or <tt>'''lsetfilecon'''(3)</tt> are used to set the context for labeling the file.
  
'''Examples'''
+
If a valid entry is not found an error is generated in the log currently formatted as follows:
 +
: <tt>seapp_context_lookup: No match for app with uid uid, seinfo seinfo, name pkgname</tt>
 +
 
 +
==== Computing Process Context Examples ====
 
The following is an example taken as the system server is loaded:
 
The following is an example taken as the system server is loaded:
 
<pre>
 
<pre>
Input selectors:
+
selinux_android_setcontext() parameters:
  uid             1000
+
    uid 1000
  isSystemServer true
+
    isSystemServer true
  seinfo         null
+
    seinfo null
  name            null
+
    pkgname null
  sebool          null
+
  
username computed from uid = system
+
seapp_contexts lookup parameters:
 +
    uid 1000
 +
    isSystemServer true
 +
    seinfo null
 +
    pkgname null
 +
    path null
  
 
Matching seapp_contexts entry:
 
Matching seapp_contexts entry:
  isSystemServer=true domain=system
+
    isSystemServer=true domain=system_server
  
 
Outputs:
 
Outputs:
  domain system
+
    domain system_server
  level s0
+
    level s0
  
Computed context u:r:system:s0
+
Computed context = u:r:system_server:s0
 +
username computed from uid = system
  
 
Result using ps -Z command:
 
Result using ps -Z command:
LABEL         USER  PID PPID NAME
+
    LABEL               USER  PID PPID NAME
u:r:system:s0 system 300  45   system_server
+
    u:r:system_server:s0 system 836 63   system_server
 
</pre>
 
</pre>
  
This is the "radio" application that is part of the platform:
+
This is the ’radio’ application that is part of the platform:
 
<pre>
 
<pre>
Input selectors:
+
selinux_android_setcontext() parameters:
  uid             1001
+
    uid 1001
  isSystemServer false
+
    isSystemServer false
  seinfo         platform
+
    seinfo platform
  name            com.android.phone
+
    pkgname com.android.phone
  sebool          null
+
 
+
seapp_contexts lookup parameters:
username computed from uid = radio
+
    uid 1001 (computes user=radio entry)
 +
    isSystemServer false
 +
    seinfo platform
 +
    pkgname com.android.phone
 +
    path null
  
 
Matching seapp_contexts entry:
 
Matching seapp_contexts entry:
  user=radio domain=radio type=radio_data_file
+
    user=radio domain=radio type=radio_data_file
  
 
Outputs:
 
Outputs:
  domain radio
+
    domain radio
  level s0
+
    level s0
  
Computed context u:r:radio:s0
+
Computed context = u:r:radio:s0
 +
username computed from uid = radio
  
 
Result using ps -Z command:
 
Result using ps -Z command:
LABEL         USER   PID PPID NAME
+
    LABEL       USER PID PPID NAME
u:r:radio:s0 radio 443  45    com.android.phone
+
    u:r:radio:s0 radio 619 62  com.android.phone
 
</pre>
 
</pre>
  
This is the "SE for Android Admin Manager" application that is part of the platform:
+
This is the 'SEAndroid Admin Manager' application that is part of the SEAndroid release, however it is treated as an untrusted app (it is installed as a privileged app):
 
<pre>
 
<pre>
Input selectors:
+
selinux_android_setcontext() parameters:
  uid             10042
+
    uid 10013
  isSystemServer false
+
    isSystemServer false
  seinfo         release
+
    seinfo default
  name            com.android.seandroid_admin
+
    pkgname com.android.seandroid_admin
  sebool          null
+
  
username computed from uid = u0_a42
+
seapp_contexts lookup parameters:
 +
    isSystemServer false
 +
    uid 10013 (computes user=_app entry)
 +
    seinfo default
 +
    pkgname com.android.seandroid_admin
 +
    path null
  
 
Matching seapp_contexts entry:
 
Matching seapp_contexts entry:
  user=_app seinfo=release domain=release_app type=platform_app_data_file
+
    user=_app domain=untrusted_app type=app_data_file levelFrom=user
  
 
Outputs:
 
Outputs:
  domain release_app
+
    domain untrusted_app
  level s0
+
    level s0:c512,c768
  
Computed context u:r:release_app:s0
+
Computed context = u:r:untrusted_app:s0:c512,c768
 +
username computed from uid = u0_a13
  
 
Result using ps -Z command:
 
Result using ps -Z command:
LABEL               USER     PID   PPID   NAME
+
    LABEL                         USER   PID PPID NAME
u:r:release_app:s0 u0_a42  827  45    com.android.seandroid_admin
+
    u:r:untrusted_app:s0:c512,c768 u0_a13 827 45   com.android.seandroid_admin
 
</pre>
 
</pre>
  
This is a third party app that also runs an isolated service:
+
This is a third party app (<tt>com.example.runisolatedservice</tt>) to run an isolated service that has been installed as a privileged app (<tt>com.se4android.isolatedservice</tt>):
 
<pre>
 
<pre>
Input selectors:
+
selinux_android_setcontext() parameters:
  uid             10046
+
    uid 10054
  isSystemServer false
+
    isSystemServer false
  seinfo         null
+
    seinfo default
  name            com.example.seandroiddemo
+
    pkgname com.example.runisolatedservice
  sebool          null
+
  
username computed from uid = u0_a46
+
seapp_contexts lookup parameters:
 +
    uid 10054 (computes user=_app entry)
 +
    isSystemServer false
 +
    seinfo default
 +
    pkgname com.example.runisolatedservice
 +
    path null
  
 
Matching seapp_contexts entry:
 
Matching seapp_contexts entry:
  user=_app domain=untrusted_app type=app_data_file levelFrom=app
+
    user=_app domain=untrusted_app type=app_data_file levelFrom=user
  
 
Outputs:
 
Outputs:
  domain untrusted_app
+
    domain untrusted_app
  levelFrom app s0:c46,c256
+
    level  s0:c512,c768
  
Computed context u:r:untrusted_app:s0:c46,c256
+
Computed context = u:r:untrusted_app:s0:c512,c768
 +
username computed from uid = u0_a54
  
 
Result using ps -Z command:
 
Result using ps -Z command:
LABEL                           USER     PID   PPID NAME
+
    LABEL USER                     PID   PPID NAME
u:r:untrusted_app:s0:c46,c256  u0_a46  855  45    com.example.seandroiddemo
+
    u:r:untrusted_app:s0:c512,c768 u0_a54 1138 64 com.example.runisolatedservice
 
</pre>
 
</pre>
 +
 +
This is the isolated service installed as a privileged app (<tt>com.se4android.isolatedservice</tt>):
 
<pre>
 
<pre>
Input selectors:
+
selinux_android_setcontext() parameters:
  uid             99000
+
    uid 99000
  isSystemServer false
+
    isSystemServer false
  seinfo         null
+
    seinfo default
  name            com.example.seandroiddemo
+
    pkgname com.se4android.isolatedservice
  sebool          null
+
 
+
seapp_contexts lookup parameters:
username computed from uid = u0_i0
+
    uid 99000 (computes user=_isolated entry)
 +
    isSystemServer false
 +
    seinfo default
 +
    pkgname com.se4android.isolatedservice
 +
    path null
  
 
Matching seapp_contexts entry:
 
Matching seapp_contexts entry:
  user=_isolated domain=isolated_app
+
    user=_isolated domain=isolated_app levelFrom=user
 +
    Note that uid's 99000-99999 are reserved for isolated services - see:
 +
        system/core/include/private/android_filesystem_config.h
  
 
Outputs:
 
Outputs:
  domain isolated_app
+
    domain isolated_app
  level s0
+
    level s0:c512,c768
  
Computed context u:r:isolated_app:s0
+
Computed context = u:r:isolated_app:s0:c512,c768
 +
username computed from uid = u0_i0
  
 
Result using ps -Z command:
 
Result using ps -Z command:
LABEL                 USER   PID   PPID NAME
+
    LABEL                         USER PID PPID NAME
u:r:isolated_app:s0   u0_i0  869  45    com.example.seandroiddemo
+
    u:r:isolated_app:s0:c512,c768 u0_i0 1140 62   com.se4android.isolatedservice
 
</pre>
 
</pre>
  
==== Computing a Directory Context ====
+
==== Computing File Context Example ====
To compute an app package directory context the <tt>selinux_android_setfilecon2</tt> function is called that will use the parameters passed, plus the contents of the <tt>seapp_contexts</tt> file. The function parameters are:
+
The following example is from the third party isolated app:
 
<pre>
 
<pre>
#include <selinux/android.h>
+
selinux_android_setfilecon() parameters:
 +
    pkgdir /data/data/com.example.runisolatedservice
 +
    pkgname com.example.runisolatedservice
 +
    seinfo default
 +
    uid 10046
  
int selinux_android_setfilecon2(const char *pkgdir, const char *pkgname, const char *seinfo, uid_t uid);
+
seapp_contexts lookup parameters:
</pre>
+
    uid 10046 (computes user=_app entry)
 
+
    isSystemServer false
The context is then computed using the information as follows:
+
    seinfo default
: <tt>pkgdir</tt> is the file or directory to be labeled with the computed context.
+
    pkgname com.example.runisolatedservice
: <tt>pkgname</tt> may be <tt>NULL</tt> or that obtained from the Android package. It will be matched against the <tt>name=</tt> entries in the <tt>seapp_contexts</tt> file.
+
    path null
: <tt>seinfo</tt> may be <tt>NULL</tt> or that obtained from the <tt>mac_permissions.xml</tt> file. It will be matched against the <tt>seinfo=</tt> entries in the <tt>seapp_contexts</tt> file.
+
: The <tt>uid</tt> is converted to a string that is then used to match the <tt>user=</tt> entries in the <tt>seapp_contexts</tt> file as follows:
+
:: If an Android system service the <tt>uid</tt> is converted to a string via an internal Android table (e.g. "radio", "system").
+
:: If an isolated service the <tt>_isolated</tt> string is used.
+
:: For any other app or service the <tt>_app</tt> is used.
+
:The remaining <tt>seapp_contexts</tt> entries will be used as follows:
+
:: The <tt>sebool=</tt> parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
+
:: The <tt>levelFrom=</tt> and <tt>level=</tt> parameters if present will be used to determine the <tt>level</tt> component of the security context.
+
:: The <tt>type=</tt> is used to set the file object context and must match a context in the policy. Determines the <tt>type</tt> component of the security context.
+
If a context is computed, it is validated against policy and if correct <tt>'''setfilecon'''(3)</tt> will then be used to label <tt>pkgdir</tt> with the computed context.
+
The following example is from a third party app:
+
<pre>
+
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:
 
Matching seapp_contexts entry:
  user=_app domain=untrusted_app type=app_data_file levelFrom=app
+
    user=_app domain=untrusted_app type=app_data_file levelFrom=user
  
 
Outputs:
 
Outputs:
  type           app_data_file
+
    type app_data_file
  levelFrom app  s0:c46,c256
+
    level s0:c512,c768
  
Computed context u:object_r:app_data_file:s0:c46,c256
+
Computed context = u:object_r:app_data_file:s0:c512,c768
 +
username computed from uid = u0_a46
  
 
Result from /data/data directory using ls -Z command:
 
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
+
    drwxr-x--x u0_a46 u0_a46 u:object_r:app_data_file:s0:c512,c768 com.example.runisolatedservice
 
</pre>
 
</pre>
  
Example <tt>ls -Z /data/data</tt> entries:
+
== property_contexts  ==
 +
This file holds property service keys and their contexts that are matched against property names using <tt>'''selabel_lookup'''(3)</tt>. The returned context will then be used as the target context as described in the example below to determine whether the property is allowed or denied (see <tt>system/core/init/property_service.c</tt> and <tt>init.c</tt>).
 +
 
 +
The build process supports additional <tt>property_contexts</tt> files allowing devices to specify their entries as described in the [[NB_SEforAndroid_1#Processing Device Policy | Processing Device Policy]] section.
 +
 
 +
When <tt>'''selabel_open'''(3)</tt> is called specifying this file it will be read into memory and sorted using <tt>'''qsort'''(3)</tt>, subsequent calls using <tt>'''selabel_lookup'''(3)</tt> will then retrieve the appropriate context based on matching the <tt>property_key</tt>.
 +
 
 +
'''Example:'''
 +
 
 +
Use <tt>adb</tt> to reload the SELinux policy:
 
<pre>
 
<pre>
drwxr-x--x u0_a35 u0_a35 u:object_r:platform_app_data_file:s0 com.android.backupconfirm
+
adb shell su 0 setprop selinux.reload_policy 1
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
+
 
</pre>
 
</pre>
  
 +
Sample <tt>property_contexts</tt> file entries are:
 +
<pre>
 +
# property_key        context to be applied on match
 +
net.rmnet            u:object_r:net_radio_prop:s0
 +
net.gprs              u:object_r:net_radio_prop:s0
 +
net.ppp              u:object_r:net_radio_prop:s0
 +
net.qmi              u:object_r:net_radio_prop:s0
 +
net.lte              u:object_r:net_radio_prop:s0
 +
net.cdma              u:object_r:net_radio_prop:s0
 +
net.dns              u:object_r:net_radio_prop:s0
 +
sys.usb.config        u:object_r:system_radio_prop:s0
 +
ril.                  u:object_r:radio_prop:s0
 +
gsm.                  u:object_r:radio_prop:s0
 +
persist.radio        u:object_r:radio_prop:s0
  
=== property_contexts File ===
+
debug.                u:object_r:debug_prop:s0
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 <tt>system/core/init/property_service.c</tt> and <tt>init.c</tt>) however there are also additional property entries for applications that require specific contexts to be set.
+
debug.db.            u:object_r:debuggerd_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
  
The build process supports additional <tt>seapp_contexts</tt> files to allow devices to specify their specific entries as described in the [[NB_SEforAndroid_1#Building the Policy | Building the Policy]] section.
+
persist.audio.        u:object_r:audio_prop:s0
 +
persist.logd.        u:object_r:logd_prop:s0
 +
persist.sys.          u:object_r:system_prop:s0
 +
persist.service.      u:object_r:system_prop:s0
 +
persist.service.bdroid. u:object_r:bluetooth_prop:s0
 +
persist.security.    u:object_r:system_prop:s0
  
When <tt>'''selabel_open'''(3)</tt> is called specifying this file it will be read into memory and sorted using <tt>'''qsort'''(3)</tt>, subsequent calls using <tt>'''selabel_lookup'''(3)</tt> will then retrieve the appropriate context.
+
# selinux non-persistent properties
 +
selinux.              u:object_r:security_prop:s0
 +
 
 +
# default property context (* is wild card match)
 +
*                    u:object_r:default_prop:s0
 +
</pre>
  
Each line within the property contexts file is as follows:
+
The property service will call <tt>selabel_lookup</tt> with parameters consisting of the handle passed from <tt>selabel_open</tt>, a buffer to hold the returned context, and the object name "<tt>selinux.reload_policy</tt>" to look-up (the final parameter is not used):
 
<pre>
 
<pre>
property_key context
+
selabel_lookup(handle, &context, "selinux.reload_policy", 1);
 
</pre>
 
</pre>
  
'''Where:'''
+
The following context will be returned as the look-up process will search for a match based on the length of the <tt>property_key</tt> (and will therefore match against "<tt>selinux.</tt>"):
: <tt>property_key</tt>
+
<pre>
:: The key used to obtain the context that may contain '<tt><nowiki>*</nowiki></tt>' for wildcard matching.
+
u:object_r:security_prop:s0
:<tt>context</tt>
+
</pre>
:: The security context that will be applied to the object.
+
  
The default <tt>property_contexts</tt> file entries are:
+
The property service will then validate whether the service has permission by issuing an <tt>'''selinux_check_access'''(3)</tt> call with the following parameters:
 
<pre>
 
<pre>
##########################
+
source context: u:r:su:s0
# property service keys
+
target context: u:object_r:security_prop:s0
#
+
class:          property_service
+
permission:     set
net.rmnet0              u:object_r:radio_prop:s0
+
</pre>
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
+
The policy would then decide whether to allow or deny the property request. Using the [[#sepolicy_check | sepolicy-check]] tool will show that this will be denied by the current policy (a <tt>dontaudit</tt> rule is in the policy, however <tt>su</tt> runs permissive anyway):
persist.sys.            u:object_r:system_prop:s0
+
<pre>
persist.service.        u:object_r:system_prop:s0
+
sepolicy-check -s su -t security_prop -c property_service -p set -P out/target/product/generic/root/sepolicy
persist.security.      u:object_r:system_prop:s0
+
echo $?
 +
1
 +
</pre>
  
# mmac persistent properties
+
== service_contexts  ==
persist.mmac.u:object_r:security_prop:s0
+
This file holds binder service keys and their contexts that are matched against binder object names using <tt>'''selabel_lookup'''(3)</tt>. The returned context will then be used as the target context as described in the example below to determine whether the binder service is allowed or denied (see <tt>frameworks/native/cmds/servicemanager/servicemanager.c</tt>).
  
# selinux non-persistent properties
+
The build process supports additional <tt>service_contexts</tt> files allowing devices to specify their entries as described in the [[NB_SEforAndroid_1#Building the Policy | Building the Policy]] section.
selinux.               u:object_r:security_prop:s0
+
+
# default property context
+
*                      u:object_r:default_prop:s0
+
  
# data partition encryption properties
+
When <tt>'''selabel_open'''(3)</tt> is called specifying this file it will be read into memory and sorted using <tt>'''qsort'''(3)</tt>, subsequent calls using <tt>'''selabel_lookup'''(3)</tt> will then retrieve the appropriate context based on matching the <tt>service_key</tt>.  
vold.                   u:object_r:vold_prop:s0
+
crypto.                u:object_r:vold_prop:s0
+
  
# ctl properties
+
'''Example:'''
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
+
</pre>
+
  
== Install MMAC File ==
+
The <tt>healthd</tt> process wants to start a binder service "<tt>batterypropreg</tt>" (see <tt>frameworks/base/services/java/com/android/server/BatteryService.java</tt>).
The <tt>mac_permissions.xml</tt> file is used to configure install-time 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.
+
# Install-time MMAC permission checking.
+
  
It is important to note that all third party apps will be subject to the <tt><nowiki><default></nowiki></tt> install MAC 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). The current <tt><nowiki><default></nowiki></tt> package policy is as follows:
+
Sample <tt>service_contexts</tt> file entries are:
 +
<pre>
 +
# service_key          context to be applied on match
 +
batteryproperties      u:object_r:healthd_service:s0
 +
batterystats          u:object_r:system_server_service:s0
 +
battery                u:object_r:system_server_service:s0
 +
 +
# default service context (* is wild card match)
 +
*                      u:object_r:default_android_service:s0
 +
</pre>
  
 +
The service manager will call <tt>selabel_lookup</tt> with parameters consisting of the handle passed from <tt>selabel_open</tt>, a buffer to hold the returned context, and the object name "<tt>batterypropreg</tt>" to look-up (the final parameter is not used):
 
<pre>
 
<pre>
<!-- All other keys -->
+
selabel_lookup(handle, &context, "batterypropreg", 1);
<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>>
+
 
</pre>
 
</pre>
  
The build process supports additional <tt>mac_permissions.xml</tt> files to allow devices to specify their specific entries as described in the [[NB_SEforAndroid_1#Building the Policy | Building the Policy]] section.
+
The following context will be returned as the look-up process will search for a match based on the length of the <tt>service_key</tt> (and will therefore match against "<tt>battery</tt>"):
 +
<pre>
 +
u:object_r:system_server_service:s0
 +
</pre>
  
==== Signature Entries ====
+
The service manager will then validate whether the service has permission by issuing an <tt>'''selinux_check_access'''(3)</tt> call with the following parameters:
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 as shown that allows the key to be extracted from a pem file as discussed in the [[#insertkeys.py | insertkeys.py]] section:
+
 
<pre>
 
<pre>
    <!-- Platform dev key in AOSP -->
+
source context: u:r:healthd:s0
    <signer signature="@PLATFORM" >
+
target context: u:object_r:system_server_service:s0
        <allow-all />
+
class:          service_manager
        <seinfo value="platform" />
+
permission:     add
     </signer>
+
 
</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.
+
The policy would then decide whether to allow or deny the service. Using the [[#sepolicy_check|sepolicy-check]] tool will show that this will be allowed by the current policy:
 +
<pre>
 +
sepolicy-check -s healthd -t system_server_service \
 +
-c service_manager -p add \
 +
-P out/target/product/generic/root/sepolicy
 +
Match found!
 +
</pre>
  
==== Policy Rules ====
+
== mac_permissions.xml  ==
The following rules have been extracted from the source <tt>mac_permissions.xml</tt> file:
+
The <tt>mac_permissions.xml</tt> file is used to configure Run/Install-time MMAC policy and provides x.509 certificate to <tt>seinfo</tt> string mapping so that Zygote spawns an app in the correct domain. See the [[#Computing a Context| Computing a Context]] section for how this is achieved using information also contained in the <tt>seapp_contexts</tt> file (AOSP and SEAndroid).
  
* A signature is a hex encoded X.509 certificate and is required for each signer tag.
+
An example AOSP <tt>mac_permissions.xml</tt> file that shows the <tt><nowiki><default></nowiki></tt> entry is:
* A <tt><nowiki><signer signature="" ></nowiki></tt> element may have multiple child elements:
+
** <tt>allow-permission</tt> : produces a set of maximal allowed permissions (whitelist).
+
** <tt>deny-permission</tt> : produces a blacklist of permissions to deny.
+
** <tt>allow-all</tt> : a wildcard tag that will allow every permission requested.
+
** <tt>package</tt> : 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 <tt><nowiki><package name=""></nowiki></tt> 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 <tt><nowiki><package name=""></nowiki></tt> tag may not contain another <tt><nowiki><package name=""></nowiki></tt> tag. If found, it's skipped.
+
* A <tt><nowiki><default></nowiki></tt> 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 <tt>deny-permission</tt> tag is found
+
** A whitelist is used if not a blacklist and at least one <tt>allow-permission</tt> tag is found
+
** A wildcard (accept all permission) policy is used if not a blacklist and not a whitelist and at least one <tt>allow-all</tt> tag is present.
+
** If a <tt><nowiki><package name=""></nowiki></tt> 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 <tt>signer</tt>, <tt>default</tt> or <tt>package</tt> tags will not be accepted.
+
* Each <tt>signer</tt> / <tt>default</tt> / global <tt>package</tt> tag is allowed to contain one <tt><nowiki><seinfo value=""/></nowiki></tt> tag. This tag represents additional information that each application can use in setting a SELinux security context on the eventual process. Any <tt><nowiki><seinfo value=""/></nowiki></tt> tag found as a child of a <tt><nowiki><package name=""></nowiki></tt> tag which is protected (sub element of <tt>signer</tt> or the <tt>default</tt> tag) is ignored. It's possible that multiple <tt>seinfo</tt> tags are relevant for one application. In the event that this happens, the <tt>seinfo</tt> 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 <tt>package</tt> policy is sought. If found, this policy mediates the install.
+
** The <tt>default</tt> 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 the default <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"?>
 +
 
<policy>
 
<policy>
 
     <!-- Platform dev key in AOSP -->
 
     <!-- Platform dev key in AOSP -->
 +
 
     <signer signature="@PLATFORM" >
 
     <signer signature="@PLATFORM" >
        <allow-all />
 
 
         <seinfo value="platform" />
 
         <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>
 
     </signer>
  
Line 489: Line 545:
 
     <default>
 
     <default>
 
         <seinfo value="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>
 
     </default>
 +
 
</policy>
 
</policy>
 
</pre>
 
</pre>
  
  
== Intent MAC Files ==
+
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 as shown that allows the key to be extracted from a <tt>pem</tt> file as discussed in the [[#insertkeys.py | insertkeys.py]] section. If a base16 key is required, it can be extracted from a package using the [[#post_process_mac_perms | post_process_mac_perms]] and [[#setool | setool]] utilities.  
There are two configuration files to support intent MAC, 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></nowiki></tt> entries defined in the <tt>mmac_types.xml</tt> file that will allow intents to be managed on a package, signature and/or permissions basis. There is also an optional <tt><nowiki><allow-all></nowiki></tt> section.
+
:: <tt>mmac_types.xml</tt> - Contains <tt><nowiki><type></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 ===
+
The file supports two entry types:
+
# An intent filter that specifies actions (intents) and the types (defined in <tt>mmac_types.xml</tt>) that can be either the source or destination of the action.
+
# An <tt><nowiki><allow-all></nowiki></tt> entry.
+
 
+
Currently the build process does not support multiple <tt>intent_mac.xml</tt> files, however this will probably change.
+
  
==== Intent Filter Entry ====
+
The build process supports additional <tt>mac_permissions.xml</tt> files allowing devices to specify their entries as described in the [[NB_SEforAndroid_1#Processing Device Policy|Processing Device Policy]] section. An example SEAndroid test device <tt>mac_permissions.xml</tt> file is:
The entries are defined below with:
+
* The <tt><nowiki><action name="" /></nowiki></tt> entry will define the intent.
+
* The <tt>src=</tt> and <tt>dst=</tt> entries may be package names or 'type names' that are further defined in the <tt>mmac_types.xml</tt> file.
+
* The <tt>srcctx=</tt> entry if defined will be matched against the app process source context.
+
 
<pre>
 
<pre>
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
<policy>                          <!-- Start intent_mac.xml entries -->
 
  
    <intent>                      <!-- Starts a new intent filter -->
+
<policy>
        <filter>
+
            <action name="" />    <!-- Only one entry allowed-->
+
        <!-- or-->
+
            <category name="" />  <!-- Multiple entries allowed -->
+
    </filter>
+
    <allow                        <!-- Multiple entries allowed -->
+
        name=""                    <!-- Rule name -->
+
        srcctx=""                  <!-- Source context to be matched -->
+
        src=""                    <!-- Source <type> entry or package name -->
+
        dst=""                    <!-- Destination <type> entry or package name -->
+
    </allow>
+
    </intent>
+
  
</policy>                          <!-- End entries -->
+
    <!-- NET_APPS key and seinfo for SE4A-NetClient & SE4A-NetServer apps. -->
</pre>
+
    <signer signature="@NET_APPS" >
 
+
        <package name="com.se4android.netclient" >
An example entry is:
+
            <seinfo value="netclient" />
<pre>
+
        </package>
<?xml version="1.0" encoding="utf-8"?>
+
        <package name="com.se4android.netserver" >
 +
            <seinfo value="netserver" />
 +
        </package>
 +
    </signer>
  
<policy>
 
    <intent>
 
        <filter>
 
            <action name="android.bluetooth.adapter.action.LOCAL_NAME_CHANGED"/>
 
        </filter>
 
        <allow src="bluetooth" dst="settings"/>
 
        <allow src="bluetooth" dst="android"/>
 
        <allow src="bluetooth" dst="settings"/>
 
    </intent>
 
 
</policy>
 
</policy>
 
</pre>
 
</pre>
  
==== Allow-all Entry ====
+
==== Policy Rules ====
The entries are defined below with:
+
The following rules have been extracted from the AOSP <tt>mac_permissions.xml</tt> file with the one SEAndroid addition noted:
  
* The <tt>src=</tt> and <tt>dst=</tt> entries are generally package names as all intents will be allowed, however they may be 'type names' that are further defined in the <tt>mmac_types.xml</tt> file.
+
* A signature is a hex encoded X.509 certificate or a tag defined in <tt>keys.conf</tt> and is required for each <tt>signer</tt> tag.
* The <tt>srcctx=</tt> entry if defined will be matched against the app process source context.
+
* A <tt>signer</tt> tag may contain a <tt>seinfo</tt> tag and multiple package stanzas.
<pre>
+
* A <tt>default</tt> tag is allowed that can contain policy for all apps not signed with a previously listed cert. It may not contain any inner <tt>package</tt> stanzas.
<?xml version="1.0" encoding="utf-8"?>
+
* Each <tt>signer</tt>/<tt>default</tt>/<tt>package</tt> tag is allowed to contain one <tt>seinfo</tt> tag. This tag represents additional info that each app can use in setting a SELinux security context on the eventual process.
<policy>                   <!-- Start intent_mac.xml entries -->
+
* When a package is installed the following logic is used to determine what <tt>seinfo</tt> value, if any, is assigned:
 +
** All signatures used to sign the app are checked first.
 +
** If a <tt>signer</tt> stanza has inner <tt>package</tt> stanzas, those stanza will be checked to try and match the package name of the app. If the package name matches then that <tt>seinfo</tt> tag is used. If no inner package matches then the outer <tt>seinfo</tt> tag is assigned.
 +
** The <tt>default</tt> tag is consulted last if needed.
 +
** If none of the cases apply then the app is denied install on the device. '''NOTE:''' This case only applies to SEAndroid.
  
    <allow-all>            <!-- Starts a new intent filter -->
+
== eops.xml  ==
        <allow              <!-- Multiple entries allowed -->
+
The following text has been taken from the SEAndroid <tt>/external/sepolicy/eops.xml</tt> file (so check if any changes) with a few minor additions (there is also a simple example in the [[#Eops Example | EOps Example]] section section).
          name=""          <!--</nowiki></tt> Rule name -->
+
          srcctx=""        <!-- Source context to be matched -->
+
          <tt>src=""        <!-- Source <type> entry or package name -->
+
          <tt>dst=""        <!-- Destination <type> entry or package name -->
+
        </allow>
+
    </allow-all>
+
</policy>                  <!-- End entries -->
+
</pre>
+
  
An <tt><nowiki><allow-all></nowiki></tt> example entry:
+
EOps (enterprise operations) is a security extension to the App Operations (AppOps) feature already present on Android 4.3+ devices. AppOps lets users fine tune certain functionality requested by apps by allowing the user to toggle these access rights.
<pre>
+
<?xml version="1.0" encoding="utf-8"?>
+
<policy>
+
  
    <allow-all>
+
EOps seeks to provide an extension whereby a hard coded set of rules explicitly denies certain access rights to groups of installed apps. This feature will allow an enterprise like control over certain operations. EOps is not a front-end for SELinux which somehow ties app permissions to SELinux contexts. Rather, it is an extension of the middleware MAC (MMAC) controls that currently exist on Android 4.3+ devices. EOps uses the <tt>seinfo</tt> labels that are already assigned to apps upon install.
        <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>
+
  
</policy>
+
The list of viable op tag names can be found in <tt>frameworks/base/core/java/android/app/AppOpsManager.java</tt>. Just use the string version of each op without the <tt>OP_</tt> prefix in your policy tags. These are the current 48 entries (March '15):
</pre>
+
  
 +
<tt>
 +
{| border="1"
 +
| COARSE_LOCATION
 +
| FINE_LOCATION
 +
| GPS
  
=== mmac_types.xml File ===
+
|-
The build process supports additional <tt>mmac_types.xml</tt> files to allow devices to specify their specific entries as described in the [#2.10.5.Building the Policy|outline Building the Policy] section that will also expand any signatures.
+
| VIBRATE
 +
| READ_CONTACTS
 +
| WRITE_CONTACTS
  
The entries are defined below with:
+
|-
* The <tt><nowiki><type name="" /></nowiki></tt> entry defines the 'type name' entry that will be referenced by the <tt>intent_mac.xml</tt> file <tt>src=""</tt> and <tt>dst=""</tt> entries. The entry will define signatures, package names and or permissions.
+
| READ_CALL_LOG
* The <tt><nowiki><signature value="" /></nowiki></tt> entries may be the key as extracted by setool (but it will need to be copied from the output produced by [[#setool | setool]]), or use the <tt>"@.."</tt> show in the example below, this will then be generated as a part of the build process by [[#insertkeys.py | insertkeys.py]].
+
| WRITE_CALL_LOG
* The <tt>srcctx=</tt> entry if defined will be matched against the app process source context.
+
| READ_CALENDAR
<pre>
+
<?xml version="1.0" encoding="utf-8"?>
+
<types>                        <!--Start entries -->
+
  
  <type name="" />            <!-- The type entries 'name' -->
+
|-
    <signature value="" />    <!-- Multiple entries allowed -->
+
| WRITE_CALENDAR
    <package value="" />      <!-- Multiple entries allowed -->
+
| WIFI_SCAN
    <permission value="" />    <!-- Rule name -->
+
| POST_NOTIFICATION
    </type>
+
  
</types>                        <!-- End entries -->
+
|-
</pre>
+
| NEIGHBORING_CELLS
 +
| CALL_PHONE
 +
| READ_SMS
  
Example entries are:
+
|-
<pre>
+
| WRITE_SMS
<nowiki><?xml version="1.0" encoding="utf-8"?></nowiki>
+
| RECEIVE_SMS
<nowiki><types></nowiki>
+
| RECEIVE_EMERGECY_SMS
    <nowiki><type name="telephony_app"></nowiki>
+
        <nowiki><signature value="@PLATFORM"/></nowiki>
+
        <nowiki><package value="com.android.phone"/></nowiki>
+
    <nowiki></type></nowiki>
+
  
    <nowiki><type name="video_perm"></nowiki>
+
|-
        <nowiki><permission value="android.permission.CAMERA"/></nowiki>
+
| RECEIVE_MMS
        <nowiki><permission value="android.permission.RECORD_AUDIO"/></nowiki>
+
| RECEIVE_WAP_PUSH
    <nowiki></type></nowiki>
+
| SEND_SMS
<nowiki></types></nowiki>
+
</pre>
+
  
 +
|-
 +
| READ_ICC_SMS
 +
| WRITE_ICC_SMS
 +
| WRITE_SETTINGS
  
== Revoke Permissions File ==
+
|-
The <tt>revoke_permissions.xml</tt> file is used to configure revoked permissions. The build process does not currently support additional files. The <tt>revoke_permissions.xml</tt> file entries are as follows:
+
| SYSTEM_ALERT_WINDOW
 +
| ACCESS_NOTIFICATIONS
 +
| CAMERA
 +
 
 +
|-
 +
| RECORD_AUDIO
 +
| PLAY_AUDIO
 +
| READ_CLIPBOARD
 +
 
 +
|-
 +
| WRITE_CLIPBOARD
 +
| TAKE_MEDIA_BUTTONS
 +
| TAKE_AUDIO_FOCUS
 +
 
 +
|-
 +
| AUDIO_MASTER_VOLUME
 +
| AUDIO_VOICE_VOLUME
 +
| AUDIO_RING_VOLUME
 +
 
 +
|-
 +
| AUDIO_MEDIA_VOLUME
 +
| AUDIO_ALARM_VOLUME
 +
| AUDIO_NOTIFICATION_VOLUME
 +
 
 +
|-
 +
| AUDIO_BLUETOOTH_VOLUME
 +
| WAKE_LOCK
 +
| MONITOR_LOCATION
 +
 
 +
|-
 +
| MONITOR_HIGH_POWER_LOCATION
 +
| GET_USAGE_STATS
 +
| MUTE_MICROPHONE
 +
 
 +
|-
 +
| TOAST_WINDOW
 +
| PROJECT_MEDIA
 +
| ACTIVATE_VPN
 +
 
 +
|}
 +
</tt>
 +
 
 +
All operations listed in the policy will have a mode of ignored. This means that empty data sets are returned to the caller when an operation is requested. This shadow data will then allow certain apps to presumably still operate. However, AOSP currently is not constructed to return these empty data sets and therefore acts as if ignored operations are completely denied (blocked). Because of this some apps might crash or behave oddly if you apply certain eops policy. In addition, while AOSP seems to have hooked the proper places to check operations against policy some of those hooks fail to follow through with the denial and still allow the operation to occur. Because of this, EOps will also fail to make those distinctions and likewise fail to enforce certain operations. Once the AOSP pieces are in place to return legitimate fake data and enforce all operations then of course eops, by its design, will also do the same.
 +
 
 +
So, as long as AppOps is beta so too will EOps.
 +
 
 +
A <tt>debug</tt> tag is also allowed which flips on the global debugging log functionality inside AppOps.
 +
 
 +
Each stanza is grouped according to the <tt>seinfo</tt> tag that is assigned during install and thus creates a dependency with the <tt>mac_permissions.xml</tt> file. Each <tt>seinfo</tt> tag can then include any number of op tags. By including the op(s) you are simply removing that operation from working for all apps that have been installed with the listed <tt>seinfo</tt> label. These operations are restricted regardless of what any user controlled app ops policy may say. Any op not listed is therefore still subject to user control as normal.
 +
 
 +
Lastly, there is no permissive mode for EOps. Once a policy is in place all ops listed are enforced.
 +
 
 +
The following is an example <tt>eops.xml</tt> policy file that will stop the camera being used by any system or default app. The file installation is shown in the [[#buildeopbundle | Build Bundle Tools - buildeopbundle]] section:
 
<pre>
 
<pre>
<?xml version="1.0" encoding="utf-8"?>
+
<?xml version="1.0"?>
<revoke-policy>                <!-- Start entries -->
+
<app-ops>
  
     <package name="" />        <!-- Package containing permissions to revoke -->
+
     <debug/>
    <revoke-permission="" />   <!-- Multiple entries allowed -->
+
 
     </package>
+
    <seinfo name="default">
 +
         <op name="CAMERA"/>
 +
    </seinfo>
 +
 
 +
    <seinfo name="system">
 +
        <op name="CAMERA"/>
 +
     </seinfo>
  
<revoke-policy>                <!-- End entries -->
+
</app-ops>
 
</pre>
 
</pre>
  
Example entries are:
+
== ifw.xml  ==
 +
The example <tt>external/sepolicy/ifw.xml</tt> file has some comments regarding the tags, there is also an overview at [http://www.cis.syr.edu/~wedu/android/IntentFirewall/ http://www.cis.syr.edu/~wedu/android/IntentFirewall/].
 +
 
 +
The following is an example <tt>ifw.xml</tt> policy file that will stop the <tt>DemoIsolatedService</tt> being used by any app other than system apps or apps with the same signature. The file installation is shown in the [[#buildifwbundle | Build Bundle Tools - buildifwbundle]] section:
 
<pre>
 
<pre>
<?xml version="1.0" encoding="utf-8"?></nowiki>
+
<?xml version="1.0"?>
<revoke-policy></nowiki>
+
  
    <package name="com.example.seandroiddemo">
+
<rules>
        <revoke-permission name="com.example.seandroiddemo.permission.DEADLY_ACTIVITY"/>
+
    </package><
+
  
     <package name="com.example.seandroiddemob">
+
     <!-- This will stop any app that is not a system app or
        <revoke-permission name="android.permission.CAMERA"/>
+
        does not have a matching signature from running the
     </package>
+
        DemoIsolatedService service
 +
     -->
  
</revoke-policy>
+
    <service log="true" block="true">
 +
        <not><sender type="system|signature"/></not><
 +
        <intent-filter />
 +
            <component-filter name="com.se4android.isolatedservice/.DemoIsolatedService"/>
 +
    </service>
 +
 
 +
</rules>
 
</pre>
 
</pre>
  
 +
The events will be in the event log under the '<tt>ifw_intent_matched</tt>' tag, for example:
 +
<pre>
 +
adb logcat -b events
 +
...
 +
...
 +
I/ifw_intent_matched( 390):[2,com.se4android.isolatedservice/.DemoIsolatedService,10058,1,NULL,NULL,NULL,NULL,0]
 +
...
 +
</pre>
  
 
= Policy Build Tools =
 
= Policy Build Tools =
This section covers the policy build tools located at <tt>external/sepolicy/tools</tt>. They are checkfc, checkseapp and insertkeys.py. There is also setool that is not used as part of the build process but generates <tt>mac_permissions.xml</tt> entries from packages.
+
This section covers the policy build tools located at <tt>external/sepolicy/tools</tt>. They are <tt>checkfc</tt>, <tt>checkseapp</tt> and <tt>insertkeys.py</tt>. There is also <tt>setool</tt> that is not used as part of the build process but generates <tt>mac_permissions.xml</tt> entries from packages.
  
 
== checkfc ==
 
== checkfc ==
The <tt>checkfc</tt> utility is used during the build process to validate the <tt>file_contexts</tt> and <tt>property_contexts</tt> files against policy. If validation fails <tt>checkfc</tt> will exit with an error.
+
The <tt>checkfc</tt> utility is used during the build process to validate the <tt>file_contexts</tt>, <tt>property_contexts</tt> and <tt>service_contexts</tt> files against policy. If validation fails <tt>checkfc</tt> will exit with an error.
  
<tt>checkfc -h</tt> will give the following output:
+
Usage:
 
<pre>
 
<pre>
usage: <nowiki>checkfc [OPTIONS] sepolicy context_file</nowiki>
+
usage: checkfc [OPTIONS] sepolicy context_file
 +
 
 
Parses a context file and checks for syntax errors.
 
Parses a context file and checks for syntax errors.
 
The context_file is assumed to be a file_contexts file
 
The context_file is assumed to be a file_contexts file
 
unless explicitly switched by an option.
 
unless explicitly switched by an option.
  
    OPTIONS:
+
OPTIONS:
        -p : context file represents a property_context file.
+
    -p : context file represents a property_context file.
 
</pre>
 
</pre>
  
Example validating <tt>file_contexts</tt> file:
+
Example validating <tt>file_contexts</tt> file (note: no <tt>-p</tt> parameter):
 
<pre>
 
<pre>
 
checkfc out/target/product/generic/root/sepolicy out/target/product/generic/root/file_contexts
 
checkfc out/target/product/generic/root/sepolicy out/target/product/generic/root/file_contexts
Line 687: Line 769:
 
The <tt>checkseapp</tt> utility is used during the build process to validate the <tt>seapp_contexts</tt> file against policy. If validation fails <tt>checkseapp</tt> will exit with an error. <tt>checkseapp</tt> also consolidates matching entries and outputs the valid file stripped of comments.
 
The <tt>checkseapp</tt> utility is used during the build process to validate the <tt>seapp_contexts</tt> file against policy. If validation fails <tt>checkseapp</tt> will exit with an error. <tt>checkseapp</tt> also consolidates matching entries and outputs the valid file stripped of comments.
  
<tt>checkseapp -h</tt> will give the following output:
+
Usage:
 
<pre>
 
<pre>
<nowiki>checkseapp [options] <input file></nowiki>
+
checkseapp [options] <input file>
<nowiki>Processes an seapp_contexts file specified by argument <input file> (default stdin) and allows later declarations to  
+
 
override previous ones on a match.</nowiki>
+
Processes an seapp_contexts file specified by argument <input file> (default stdin) and allows later declarations to override previous ones on a match.
 +
 
 
Options:
 
Options:
 
     -h - print this help message
 
     -h - print this help message
 +
    -s - enable strict checking of duplicates. This causes the program to exit on a duplicate entry with a non-zero exit status
 
     -v - enable verbose debugging informations
 
     -v - enable verbose debugging informations
     -p policy file - specify policy file for strict checking of output selectors
+
     -p policy file - specify policy file for strict checking of output selectors against the policy
 
     -o output file - specify output file, default is stdout
 
     -o output file - specify output file, default is stdout
 
</pre>
 
</pre>
Line 701: Line 785:
 
An example command with output to <tt>stdout</tt> is:
 
An example command with output to <tt>stdout</tt> is:
 
<pre>
 
<pre>
checkseapp -p out/target/product/generic/root/sepolicy out/target/product/generic/root/seapp_contexts
+
checkseapp -p out/target/product/se4a_device/root/sepolicy out/target/product/se4a_device/root/seapp_contexts
isSystemServer=true domain=system
+
 
user=system domain=system_app type=system_data_file
+
isSystemServer=true domain=system_server
 +
user=system domain=system_app type=system_app_data_file
 
user=bluetooth domain=bluetooth type=bluetooth_data_file
 
user=bluetooth domain=bluetooth type=bluetooth_data_file
 
user=nfc domain=nfc type=nfc_data_file
 
user=nfc domain=nfc type=nfc_data_file
 
user=radio domain=radio type=radio_data_file
 
user=radio domain=radio type=radio_data_file
user=_app domain=untrusted_app type=app_data_file levelFrom=app
+
user=shared_relro domain=shared_relro
user=_app seinfo=platform domain=platform_app type=platform_app_data_file
+
user=shell domain=shell type=shell_data_file
user=_app seinfo=shared domain=shared_app type=platform_app_data_file
+
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=media domain=media_app type=platform_app_data_file
+
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app seinfo=release domain=release_app type=platform_app_data_file
+
user=_app domain=untrusted_app type=app_data_file levelFrom=user
user=_isolated domain=isolated_app
+
user=_app seinfo=netclient domain=netclient_app type=net_apps_log_file levelFrom=app
 +
user=_app seinfo=netserver domain=netserver_app type=net_apps_log_file levelFrom=app
 
</pre>
 
</pre>
  
== 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> and <tt>mmac_types.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.
+
The <tt>insertkeys.py</tt> utility is used during the build process to insert signing keys into the <tt>mac_permissions.xml</tt> file. 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 File | keys.conf File]] 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.
+
<tt>insertkeys.py</tt> generates base16 encodings from the base64 <tt>pem</tt> files as this is required by the Android Package Manager Service. The resulting <tt>mac_permissions.xml</tt> file will also be stripped of comments and whitespace.
  
<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.
+
Usage:
 
+
<tt>insertkeys.py -h</tt> will give the following output:
+
 
<pre>
 
<pre>
<nowiki>Usage: insertkeys.py [options] CONFIG_FILE MAC_PERMISSIONS_FILE [MAC_PERMISSIONS_FILE...]</nowiki>
+
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. If multiple mac_permission.xml files are included then they are unioned to produce a final version.
If multiple mac_permission.xml files are included then they are unioned to produce a final version.
+
  
 
Options:
 
Options:
     --version show program's version number and exit
+
     --version               show program's version number and exit
     -h, --help show this help message and exit
+
     -h,     --help         show this help message and exit
     -v, --verbose Print internal operations to stdout
+
     -v,     --verbose     Print internal operations to stdout
     -o FILE, --output=FILE Specify an output file, default is 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
+
     -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
+
     -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>
  
An example command that takes two <tt>mac_permission.xml</tt> files inserts the signatures and concatenates them into a single file is:
+
=== keys.conf File ===
 +
The <tt>keys.conf</tt> file is used by <tt>insertkeys.py</tt> for mapping the "<tt>@...</tt>" tags in <tt>mac_permissions.xml</tt>, <tt>mmac_types.xml</tt> and <tt>content_provider.xml</tt> signature entries with public keys found in <tt>pem</tt> files. The configuration file can be used in the <tt>BOARD_SEPOLICY_UNION</tt> variable and is processed via <tt>m4</tt> macros.
 +
 
 +
<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:
 
<pre>
 
<pre>
insertkeys.py -o demo/unioned_mac_permissions.xml external/sepolicy/keys.conf \
+
#
external/sepolicy/mac_permissions.xml demo/mac_permissions.xml
+
# Maps an arbitrary tag [TAGNAME] with the string contents found in
 +
# TARGET_BUILD_VARIANT. 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. Typcially this is user, eng, and userdebug. Another
 +
# option is to use ALL which will match ANY TARGET_BUILD_VARIANT string.
 +
#
 +
 
 +
[@PLATFORM]
 +
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/platform.x509.pem
 +
 
 +
[@MEDIA]
 +
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/media.x509.pem
 +
 
 +
[@SHARED]
 +
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/shared.x509.pem
 +
 
 +
# Example of ALL TARGET_BUILD_VARIANTS
 +
[@RELEASE]
 +
ENG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
 +
USER : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
 +
USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
 
</pre>
 
</pre>
  
=== keys.conf ===
+
The following is an example entry that will use a device specific key during the build process:
The <tt>keys.conf</tt> file is used by <tt>insertkeys.py</tt> for mapping the "<tt>@...</tt>" tags in <tt>mac_permissions.xml</tt> and mmac_types.xml signature entries with public keys found in <tt>pem</tt> files. The configuration file can be used in <tt>BOARD_SEPOLICY_UNION</tt> and <tt>BOARD_SEPOLICY_REPLACE</tt> variables and is processed via <tt>m4</tt> macros.
+
<pre>
 +
[@NET_APPS]
 +
ALL : $ANDROID_BUILD_TOP/device/demo_vendor/se4a_device/security/net_apps.x509.pem
 +
</pre>
  
<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>.
+
== Build Bundle Tools ==
 +
The following tools will produce an Android "bundle" for updating MAC/MMAC policy within a zip file suitable for installation by the SEAdmin app. SEAdmin is currently hard-coded to look for these zip files in the SD Card device (<tt>/sdcard/</tt>).
  
An example <tt>keys.conf</tt> file is as follows:
+
The [[#Using an Intent Example | buildsebundle]] section also shows how a policy can be updated by broadcasting an intent instead of using SEAdmin.
 +
 
 +
=== buildsebundle ===
 +
The <tt>buildsebundle</tt> tool will produce an Android "bundle" for updating the core SE for Android policy within an <tt>selinux_bundle.zip</tt> file, suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the [[#Using an Intent Example | Using an Intent Example]] section.
 +
 
 +
To be able to build the bundle the following mandatory files are required:
 +
: <tt>selinux_version</tt>, <tt>sepolicy</tt>, <tt>file_contexts</tt>, <tt>seapp_contexts</tt>, <tt>property_contexts</tt>, <tt>service_contexts</tt>, <tt>mac_permissions.xml</tt>
 +
 
 +
Usage:
 
<pre>
 
<pre>
<nowiki>#</nowiki>
+
usage: buildsebundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
<nowiki># Maps an arbitrary tag [TAGNAME] with the string contents found in</nowiki>
+
    [-h] -- <selinux_version> <file_contexts> <property_contexts> \
<nowiki># TARGET_BUILD_VARAINT. Common convention is to start TAGNAME with an @ and</nowiki>
+
    <sepolicy> <seapp_contexts> <service_contexts> <mac_permissions.xml>
<nowiki># name it after the base file name of the pem file.</nowiki>
+
<nowiki>#</nowiki>
+
<nowiki># Each tag (section) then allows one to specify any string found in</nowiki>
+
<nowiki># TARGET_BUILD_VARIANT. Typically this is user, eng, and userdebug. Another</nowiki>
+
<nowiki># option is to use ALL which will match ANY TARGET_BUILD_VARAINT string.</nowiki>
+
<nowiki>#</nowiki>
+
  
<nowiki>[@PLATFORM]</nowiki>
+
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:
ALL : build/target/product/security/platform.x509.pem
+
    build/target/product/security/testkey.pk8
  
<nowiki>[@MEDIA]</nowiki>
+
The built bundle will be written to selinux_bundle.zip which will include the signature metadata file of the bundle.
ALL : build/target/product/security/media.x509.pem
+
  
<nowiki>[@SHARED]</nowiki>
+
OPTIONS:
ALL : build/target/product/security/shared.x509.pem
+
    -h Show this message.
 +
    -v Version of the built bundle. Defaults to 1.
 +
    -r SHA-512 hash of the bundle to replace. Defaults to 'NONE'.
 +
</pre>
  
<nowiki># Example of ALL TARGET_BUILD_VARIANTS</nowiki>
+
The following is an example where a new policy has been built with all required files. The wildcard can be used as <tt>buildsebundle</tt> will always use the mandatory list:
<nowiki>[@RELEASE]</nowiki>
+
<pre>
ENG : build/target/product/security/testkey.x509.pem
+
buildsebundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 \
USER : build/target/product/security/testkey.x509.pem
+
-v 3 -- $ANDROID_BUILD_TOP/device/demo_device/se4a_device/new_sepolicy/*
USERDEBUG : build/target/product/security/testkey.x509.pem
+
 
 +
adb push selinux_bundle.zip /sdcard/
 
</pre>
 
</pre>
  
== setool ==
+
Once built, the bundle is pushed to the SD card and SEAdmin is used to update the policy (note that SEAdmin only reads the bundle from <tt>/sdcard</tt>).
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 entries produced will generally have to be modified because currently:
+
==== Using an Intent Example ====
# 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-time MMAC process (therefore the packages need to be consolidated into on entry).
+
This example shows how to update a policy by broadcasting an intent in the same way as SEAdmin.
# <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-time 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.
+
  
Having said that, <tt>setool</tt> is still useful as it will generate the signature entries and extract the permissions.  
+
Extract the <tt>selinux_bundle</tt> files from the <tt>selinux_bundle.zip</tt> file:
 +
<pre>
 +
unzip selinux_bundle.zip
 +
Archive: selinux_bundle.zip
 +
    inflating: update_bundle
 +
    inflating: update_bundle_metadata
 +
</pre>
  
<tt>setool --help</tt> will give the following output:
+
The two files contain:
 +
 
 +
: <tt>'''update_bundle'''</tt> - Contains hex encoded policy files to be installed.
 +
: <tt>'''update_bundle_metadata'''</tt> - This is used by SEAdmin to form the intent and contains a hash of the bundle to replace or "<tt>NONE</tt>", the signature of the <tt>update_bundle</tt> and the bundle version (in this case "<tt>3</tt>"). Example contents are:
 
<pre>
 
<pre>
Usage: setool [flags] <--build|--policy> <apks>
+
NONE:I6E0cZ8WbF6kJWkDozJCfckw5xuZhXuE0iqrbszsxhi7S4Z3DrR7RiH/aomRQxeskvMv9B/+G7JXfxFAQlV1CWZihnefkHGnei4atKnBLPK/g3gmf0Wb0jjizc4yb4uvu/XQAZvybKcsTvTiegfqTHMFWPGKgoq97RKAjk2kT2fa3liArylTrLl7OfRtKq6mNjQNnfVrte9e/aJptiAmOwDNdQydfRwhewrKPE6rM+YNuHJaJ+h28dNecQtCn9TabTxn8I1G+10d5/wmjjgXq6MdfEMQZ++H4ZIaL4bTdUOQVdFeMsnFLA3hjLGf3BXpHmG84s7iDO158V0kbXikzA==:3
 +
</pre>
 +
 
 +
Push the <tt>update_bundle</tt> to the device:
 +
<pre>
 +
adb push update_bundle /data/update_bundle
 +
</pre>
 +
 
 +
Build an intent to broadcast via <tt>adb</tt> by including the bundle location, with the hash, signature and version from the <tt>update_bundle_metadata</tt> as follows:
 +
<pre>
 +
adb shell am broadcast -a android.intent.action.UPDATE_SEPOLICY -e "CONTENT_PATH" "/data/update_bundle" -e "REQUIRED_HASH" "NONE" -e "SIGNATURE" "I6E0cZ8WbF6kJWkDozJCfckw5xuZhXuE0iqrbszsxhi7S4Z3DrR7RiH/aomRQxeskvMv9B/+G7JXfxFAQlV1CWZihnefkHGnei4atKnBLPK/g3gmf0Wb0jjizc4yb4uvu/XQAZvybKcsTvTiegfqTHMFWPGKgoq97RKAjk2kT2fa3liArylTrLl7OfRtKq6mNjQNnfVrte9e/aJptiAmOwDNdQydfRwhewrKPE6rM+YNuHJaJ+h28dNecQtCn9TabTxn8I1G+10d5/wmjjgXq6MdfEMQZ++H4ZIaL4bTdUOQVdFeMsnFLA3hjLGf3BXpHmG84s7iDO158V0kbXikzA==" -e "VERSION" "3"
 +
</pre>
 +
 
 +
When the intent has been broadcast there will be a response, however that does not indicate that the policy was updated, just that the intent was broadcast:
 +
<pre>
 +
Broadcasting: Intent { act=android.intent.action.UPDATE_SEPOLICY (has extras) }
 +
Broadcast completed: result=0
 +
</pre>
 +
 
 +
<tt>logcat</tt> should show whether it was successful:
 +
<pre>
 +
I/ConfigUpdateInstallReceiver( 908): Found new update, installing...
 +
I/ConfigUpdateInstallReceiver( 908): Installation successful
 +
I/SELinuxPolicyInstallReceiver( 908): Applying SELinux policy
 +
</pre>
 +
If the update failed because of versioning then an error is given (however if signature incorrect fails silently).
 +
 
 +
The following show various policy information after the third update:
 +
<pre>
 +
adb shell ls -l /data/security/current
 +
lrwxrwxrwx system system 2014-07-19 10:41 current -> /data/security/contexts
 +
</pre>
 +
<pre>
 +
adb shell ls -l /data/security/contexts
 +
 
 +
-rw-r--r-- system system 10512 2014-07-19 10:41 file_contexts
 +
-rw-r--r-- system system 10656 2014-07-19 09:01 file_contexts_backup
 +
-rw-r--r-- system system 4203 2014-07-19 10:41 mac_permissions.xml
 +
-rw-r--r-- system system 4203 2014-07-19 09:01 mac_permissions.xml_backup
 +
-rw-r--r-- system system 2549 2014-07-19 10:41 property_contexts
 +
-rw-r--r-- system system 2549 2014-07-19 09:01 property_contexts_backup
 +
-rw-r--r-- system system 641 2014-07-19 10:41 seapp_contexts
 +
-rw-r--r-- system system 641 2014-07-19 09:01 seapp_contexts_backup
 +
-rw-r--r-- system system 78 2014-07-19 10:41 selinux_version
 +
-rw-r--r-- system system 78 2014-07-19 09:01 selinux_version_backup
 +
-rw-r--r-- system system 115831 2014-07-19 10:41 sepolicy
 +
-rw-r--r-- system system 116438 2014-07-19 09:01 sepolicy_backup
 +
-rw-r--r-- system system 7748 2014-07-19 10:41 service_contexts
 +
-rw-r--r-- system system 7748 2014-07-19 09:01 service_contexts_backup
 +
</pre>
 +
<pre>
 +
adb shell ls -l /data/security
 +
 
 +
drwx------ system system 2014-07-19 10:41 bundle
 +
drwx------ system system 2014-07-19 10:41 contexts
 +
lrwxrwxrwx system system 2014-07-19 10:41 current ->/data/security/contexts
 +
drwx------ system system 2014-07-19 10:37 eops
 +
</pre>
 +
<pre>
 +
adb shell ls -l /data/security/bundle
 +
 
 +
drwx------ system system 2014-07-19 10:41 metadata
 +
-rw-r--r-- system system 191271 2014-07-19 10:41 sepolicy_bundle
 +
</pre>
 +
<pre>
 +
adb shell ls -l /data/security/bundle/metadata
 +
 
 +
-rw-r--r-- system system 1 2014-07-19 10:41 version
 +
</pre>
 +
<pre>
 +
adb shell cat /data/security/bundle/metadata/version
 +
3
 +
</pre>
 +
 
 +
The loaded policy can be extracted from the device if required by:
 +
<pre>
 +
adb pull /sys/fs/selinux/policy sepolicy-v3
 +
</pre>
 +
 
 +
=== buildeopbundle ===
 +
The <tt>buildeopbundle</tt> tool will produce an Android "bundle" for updating the Enterprise Operations policy within an <tt>eops_bundle.zip</tt> file suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the [[#Using an Intent Example | Using an Intent Example]] section.
 +
 
 +
To be able to build the bundle an <tt>eops.xml</tt> file is required.
 +
 
 +
Usage:
 +
<pre>
 +
usage: buildeopbundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
 +
[-h] -- <eops.xml>
 +
 
 +
This script builds a eops 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 a key size of at least 1024 or greater. The bundle requires that the eops.xml file be included and with that exact basename. The built bundle will be written to eop_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  SHA-512 hash of the bundle to replace. Defaults to 'NONE'.
 +
</pre>
 +
 
 +
==== Eops Example ====
 +
The following is an example where a new <tt>eops.xml</tt> file has been produced, bundled, then pushed to the SD card. SEAdmin is then used to update the policy (note that SEAdmin only reads the bundle from <tt>/sdcard</tt>):
 +
<pre>
 +
buildeopbundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -v 1 -- eops.xml
 +
 
 +
adb push eops_bundle.zip /sdcard/
 +
</pre>
 +
 
 +
<tt>logcat</tt> should show if it was successful:
 +
<pre>
 +
D/SEAdminConfigUpdateFragment( 904): android.intent.action.UPDATE_EOPS intent being broadcast. Bundle[{CONTENT_PATH=/cache/eops_bundle, SIGNATURE=qZJ8I07MHFTXaII2jhPMooRLzejArUI0qsvkteG9nzEzgzjwyh8RWUaaRil6xrQsPb5g+qWj+nfQCkH7DIEow/WF8S1sTeReS8G/z+hPQi0MHgWGKH0kCIfXn6yqqEri3+Dnolb1vHVuM7t/0mszCvtjqfq5GWbHZc1xYSgMQJXqrhfzSqa2zvO4+7zE0GszfuZXwt9QHci9C1IJ5B50URmmg4TDIuhfISWW9vYkEctwARIyCLhfYiZzIQOwzPj3oSHI1AUWMHxbbpADFzCumZ1WdfpA0txow8rDM+01qkKGtcAsNs8me2FAPz28tckQ9ea6QwAzDCSP3PzQC1Horg==, REQUIRED_HASH=NONE, VERSION=1}]
 +
I/ConfigUpdateInstallReceiver( 395): Couldn't find current metadata, assuming first update
 +
I/ConfigUpdateInstallReceiver( 395): Failed to read current content, assuming first update!
 +
I/ConfigUpdateInstallReceiver( 395): Found new update, installing...
 +
I/ConfigUpdateInstallReceiver( 395): Installation successful
 +
D/AppOps ( 381): Eops policy: system [ CAMERA]
 +
D/AppOps ( 381): Eops policy: default [ CAMERA]
 +
</pre>
 +
 
 +
The new file and its supporting metadata are:
 +
<pre>
 +
adb shell su 0 ls -lR /data/security/eops
 +
 
 +
/data/security/eops:
 +
-rw-r--r-- system system 189 2014-07-20 14:15 eops.xml
 +
drwx------ system system 2014-07-20 14:15 eops_metadata
 +
 
 +
/data/security/eops/eops_metadata:
 +
-rw-r--r-- system system 1 2014-07-20 14:15 version
 +
</pre>
 +
 
 +
The version number after the update is:
 +
<pre>
 +
adb shell su 0 cat /data/security/eops/eops_metadata/version
 +
1
 +
</pre>
 +
 
 +
Because the Eops policy specified an <tt>seinfo</tt> of <tt>system</tt> and the operation <tt>CAMERA</tt>, if the Camera app is now started it will load however, it will not be possible to take pictures as <tt>logcat</tt> will show:
 +
<pre>
 +
D/AppOps ( 381): startOperation: reject #1 for code 26 (26) uid 10026 package com.android.camera2
 +
I/CameraService( 60): Camera 0: Access for "com.android.camera2" has been revoked
 +
</pre>
 +
 
 +
=== buildifwbundle ===
 +
The <tt>buildifwbundle</tt> tool will produce an Android "bundle" for updating the Intent Firewall policy within an <tt>ifw_bundle.zip</tt> file suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the [[#Using an Intent Example | Using an Intent Example]] section.
 +
 
 +
To be able to build the bundle an <tt>ifw.xml</tt> file is required, although note that the Intent Firewall service will read any file so long as it has the <tt>.xml</tt> extension.
 +
 
 +
Usage:
 +
<pre>
 +
usage: buildifwbundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
 +
[-h] -- <ifw.xml>
 +
 
 +
This script builds an intent firewall 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 a key size of at least 1024 or greater. The bundle requires that the ifw.xml file be included and with that exact basename. The built bundle will be written to ifw_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 SHA-512 hash of the bundle to replace. Defaults to 'NONE'.
 +
</pre>
 +
 
 +
==== IFW Example ====
 +
The following is an example where a new <tt>ifw.xml</tt> file has been produced, bundled, and then pushed to the SD card. SEAdmin is then used to update the policy (note that SEAdmin only reads the bundle from <tt>/sdcard</tt>):
 +
<pre>
 +
buildsifwbundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -v 1 -- eops.xml
 +
 
 +
adb push ifw_bundle.zip /sdcard/
 +
</pre>
 +
 
 +
<tt>logcat</tt> should show whether it was successful:
 +
<pre>
 +
D/SEAdminConfigUpdateFragment( 904): android.intent.action.UPDATE_INTENT_FIREWALL intent being broadcast. Bundle[{CONTENT_PATH=/cache/ifw_bundle, SIGNATURE=tfQONpEZbL1Y6sXj1BY98TO4izK2IyeqO9Hko5tZygE77zry98RGmU5BAAIFs21G9G7WpAcPTR7TGe4LRMpB7SKeZ1Xh+4B+U+30TnHkwXp9HRIgIJcN5Kqiyp/UPAjEJjYmBZk+yM5FLYcMCQS082wfpC9c+gRQcl6AYuSmiynvjgc1d33rtfB7Hd40LF30mBZyyiUJc5YF1ddaITBbL/CCKmFblfBqadZtmCN7xGUIJEHqWPnuEvscatkOLgZa+35ZXfl2WkD/DsGkwocXM9akjD0NJY9WZJpzwAHQPdQFXN6nthrsV8kiC7OUFvK/PKll9oetiyTSEEVH5JlMnA==, REQUIRED_HASH=NONE, VERSION=1}]
 +
I/ConfigUpdateInstallReceiver( 395): Couldn't find current metadata, assuming first update
 +
I/ConfigUpdateInstallReceiver( 395): Failed to read current content, assuming first update!
 +
I/ConfigUpdateInstallReceiver( 395): Found new update, installing...
 +
I/ConfigUpdateInstallReceiver( 395): Installation successful
 +
I/IntentFirewall( 395): Read new rules (A:0 B:0 S:1)
 +
</pre>
 +
 
 +
The new file and its supporting metadata are:
 +
<pre>
 +
adb shell su 0 ls -lR /data/system/ifw
 +
 
 +
/data/system/ifw:
 +
-rw-r--r-- system system 454 2014-07-20 13:14 ifw.xml
 +
drwx------ system system 2014-07-20 13:14 metadata
 +
 
 +
/data/system/ifw/metadata:
 +
-rw-r--r-- system system 1 2014-07-20 13:14 gservices.version
 +
</pre>
 +
 
 +
The version number after the update is:
 +
<pre>
 +
adb shell su 0 cat /data/system/ifw/metadata/gservices.version
 +
1
 +
</pre>
 +
 
 +
== post_process_mac_perms ==
 +
This tool will modify an existing <tt>mac_permissions.xml</tt> with additional app certs not already found in that policy. This becomes useful when a directory containing apps is searched and the certs from those apps are added to the policy not already explicitly listed.
 +
 
 +
There is no make target for this tool (python script), so either move to <tt>HOST_EXECUTABLE</tt> or execute directly (e.g. <tt>$PREFIX/external/sepolicy/tools/post_process_mac_perms</tt>).
 +
 
 +
Usage:
 +
<pre>
 +
post_process_mac_perms [-h] -s SEINFO -d DIR -f POLICY
 +
 
 +
  -s SEINFO, --seinfo SEINFO seinfo tag for each generated stanza
 +
  -d DIR, --dir DIR Directory to search for apks
 +
  -f POLICY, --file POLICY mac_permissions.xml policy file
 +
</pre>
 +
 
 +
Example:
 +
<pre>
 +
post_process_mac_perms -s netapps -d ./APK -f mac_permissions.xml
 +
</pre>
 +
 
 +
Before:
 +
<pre>
 +
<?xml version="1.0" encoding="utf-8"?>
 +
<policy>
 +
    <signer signature="- certificate here -" ><seinfo value="platform"/></signer>
 +
    <default><seinfo value="default"/></default>
 +
</policy>
 +
</pre>
 +
 
 +
After:
 +
<pre>
 +
<?xml version="1.0" encoding="utf-8"?>
 +
<policy>
 +
    <signer signature="- certificate here -" ><seinfo value="platform"/></signer>
 +
    <default><seinfo value="default"/></default>
 +
    <signer signature="- certificate here -"><seinfo value="netapps"/></signer>
 +
</policy>
 +
</pre>
 +
 
 +
== sepolicy_check ==
 +
A tool for auditing a <tt>sepolicy</tt> file for any allow rule that grants a given permission.
 +
 
 +
Usage:
 +
<pre>
 +
sepolicy-check -s <domain> -t <type> -c <class> -p <permission>
 +
-P out/target/product/<board>/root/sepolicy
 +
</pre>
 +
 
 +
The output will be "<tt>Match found!</tt>" or silent if not. <tt>sepolicy_check</tt> will return <tt>0</tt> for found, <tt>1</tt> for not found and <tt>-1</tt> for an error.
 +
 
 +
Examples:
 +
<pre>
 +
sepolicy-check -s healthd -t system_server_service \
 +
  -c service_manager -p add \
 +
  -P  out/target/product/generic/root/sepolicy
 +
  Match found!
 +
</pre>
 +
<pre>
 +
<tt>sepolicy-check -s su -t security_prop -c property_service \</tt>
 +
-p set -P out/target/product/generic/root/sepolicy
 +
  echo $?
 +
  1
 +
</pre>
 +
 
 +
== sepolicy-analyze ==
 +
This is the text from the <tt>external/sepolicy/tools/README</tt> that describes the tool for performing various kinds of analysis on a sepolicy file. The analysis currently supported includes:
 +
 
 +
=== Type Equivalence ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -e
 +
</pre>
 +
Display all <tt>[[TypeStatements#type | type]]</tt> pairs that are "equivalent", i.e. they are identical with respect to <tt>[[AVCRules#allow | allow]]</tt> rules, including indirect allow rules via attributes and default-enabled conditional rules (i.e. default boolean values yield a true conditional expression).
 +
 
 +
Equivalent types are candidates for being coalesced into a single type.  However, there may be legitimate reasons for them to remain separate, for example: - the types may differ in a respect not included in the current analysis, such as default-disabled conditional rules, audit-related rules (<tt>auditallow</tt> or <tt>dontaudit</tt>), default type transitions, or constraints (e.g. mls), or - the current policy may be overly permissive with respect to one or the other of the types and thus the correct action may be to tighten access to one or the other rather than coalescing them together, or - the domains that would in fact have different accesses to the types may not yet be defined or may be unconfined in the policy you are analyzing.
 +
 
 +
Example output:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy typecmp -e
 +
 
 +
Types adbd_socket and mdns_socket are equivalent.
 +
Types wifip2p_service and network_score_service are equivalent.
 +
Types wifip2p_service and registry_service are equivalent.
 +
...
 +
Types rild_debug_socket and init_tmpfs are equivalent.
 +
Types ram_device and vcs_device are equivalent.
 +
Types ram_device and uio_device are equivalent.
 +
..
 +
Types loop_device and vold_device are equivalent.
 +
</pre>
 +
 
 +
=== Type Difference ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -d
 +
</pre>
 +
Display <tt>[[TypeStatements#type | type]]</tt> pairs that differ and the first difference found between the two types.  This may be used in looking for similar types that are not equivalent but may be candidates for coalescing.
 +
 
 +
Example output:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy typecmp -d
 +
 
 +
Types adbd_socket and functionfs differ, starting with:
 +
    allow adbd_socket rootfs:filesystem {  associate };
 +
    allow functionfs self:filesystem {  associate };
 +
 
 +
Types adbd_socket and wifip2p_service differ, starting with:
 +
    allow adbd_socket rootfs:filesystem {  associate };
 +
    allow system_server wifip2p_service:service_manager {  add find };
 +
...
 +
...
 +
Types mtd_device and log_device differ, starting with:
 +
    allow mtd_device tmpfs:filesystem {  associate };
 +
 
 +
Types goldfish_setup_exec and log_device differ, starting with:
 +
    allow goldfish_setup_exec rootfs:filesystem {  associate };
 +
</pre>
 +
 
 +
=== Duplicate Allow Rules ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy dups
 +
</pre>
 +
Displays duplicate <tt>[[AVCRules#allow | allow]]</tt> rules, i.e. pairs of allow rules that grant the same permissions where one allow rule is written directly in terms of individual types and the other is written in terms of attributes associated with those same types.  The rule with individual types is a candidate for removal.  The rule with individual types may be directly represented in the source policy or may be a result of expansion of a type negation (e.g. domain -foo -bar is expanded to individual allow rules by the policy
 +
compiler).  Domains with unconfineddomain (this was removed in 5.1) will typically have such duplicate rules as a natural side effect and can be ignored.
 +
 
 +
Example output:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy dups
 +
 
 +
Duplicate allow rule found:
 +
    allow system_server sdcardd:lnk_file {  ioctl read getattr lock open };
 +
    allow system_server domain:lnk_file {  ioctl read getattr lock open };
 +
 
 +
Duplicate allow rule found:
 +
    allow system_server inputflinger:binder {  transfer };
 +
    allow system_server binderservicedomain:binder {  call transfer };
 +
...
 +
...
 +
Duplicate allow rule found:
 +
    allow su keystore:binder {  call transfer };
 +
    allow appdomain binderservicedomain:binder {  call transfer };
 +
 
 +
Duplicate allow rule found:
 +
    allow untrusted_app keystore:fd {  use };
 +
    allow appdomain binderservicedomain:fd {  use };
 +
</pre>
 +
 
 +
=== Permissive Domains ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy permissive
 +
</pre>
 +
Displays domains in the policy that are <tt>[[TypeStatements#permissive | permissive]]</tt>, i.e. avc denials are logged but not enforced for these domains.  While permissive domains can be helpful during development, they should not be present in a final <tt>-user</tt> build.
 +
 
 +
Example output on an ENG policy:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy permissive
 +
 
 +
su
 +
</pre>
 +
 
 +
=== Booleans ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy booleans
 +
</pre>
 +
Displays the <tt>[[ConditionalStatements | boolean]]</tt> names in the policy (if any).
 +
Policy booleans are forbidden in Android policy, so if there is any output, the policy will fail CTS.
 +
 
 +
 
 +
=== Attribute ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy attribute <name>
 +
</pre>
 +
Displays the <tt>[[TypeStatements#type | type]]</tt>s associated with the specified <tt>[[TypeStatements#attribute | attribute]]</tt> name.
 +
 
 +
Example output:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy attribute mlstrustedsubject
 +
 
 +
system_server
 +
netd
 +
zygote
 +
debuggerd
 +
kernel
 +
drmserver
 +
keystore
 +
adbd
 +
dumpstate
 +
runas
 +
uncrypt
 +
installd
 +
init
 +
radio
 +
mediaserver
 +
logd
 +
su
 +
mdnsd
 +
surfaceflinger
 +
racoon
 +
vold
 +
shell
 +
lmkd
 +
servicemanager
 +
</pre>
 +
 
 +
=== Neverallow Checking ===
 +
<pre>
 +
sepolicy-analyze out/target/product/<board>/root/sepolicy neverallow [-w] [-d] [-f neverallows.conf] | [-n "neverallow string"]
 +
</pre>
 +
Check whether the <tt>sepolicy</tt> file violates any of the <tt>[[AVCRules#neverallow | neverallow]]</tt> rules from the <tt>neverallows.conf</tt> file or a given string,  which contain <tt>neverallow</tt> statements in the same format as the SELinux <tt>policy.conf</tt> file, i.e. after m4 macro expansion of the rules from a <tt>.te</tt> file.  You can use an entire <tt>policy.conf</tt> file as the <tt>neverallows.conf</tt> file and <tt>sepolicy-analyze</tt> will ignore everything except for the neverallows within it.  You can also specify this as a command-line string argument, which could be useful for quickly checking an individual expanded rule or group of rules. If there are no violations, <tt>sepolicy-analyze</tt> will exit successfully with no output. Otherwise, <tt>sepolicy-analyze</tt> will report all violations and exit with a non-zero exit status.
 +
 
 +
The <tt>-w</tt> or <tt>--warn</tt> option may be used to warn on any types, attributes, classes, or permissions from a <tt>neverallow</tt> rule that could not be resolved
 +
within the <tt>sepolicy</tt> file.  This can be normal due to differences between the policy from which the <tt>neverallow</tt> rules were taken and the policy
 +
being checked.  Such values are ignored for the purposes of <tt>neverallow</tt> checking.
 +
 
 +
The <tt>-d</tt> or <tt>--debug</tt> option may be used to cause sepolicy-analyze to emit the <tt>neverallow</tt> rules as it parses them.  This is principally a debugging facility for the parser but could also be used to extract <tt>neverallow</tt> rules from a full <tt>policy.conf</tt> file and output them in a more easily parsed format.
 +
 
 +
These <tt>neverallow</tt> rules are also used by the Andriod CTS to check for policy conformance, see <tt>cts/tools/selinux/SELinuxNeverallowTestGen.py</tt> that generates Java methods.
 +
 
 +
Example output using the <tt>-d</tt> option:
 +
<pre>
 +
sepolicy-analyze out/target/product/generic/root/sepolicy neverallow -d -f out/target/product/generic/obj/ETC/sepolicy_intermediates/policy.conf
 +
 
 +
neverallow domain kernel : process { transition dyntransition };
 +
neverallow kernel { file_type fs_type - rootfs } : file { entrypoint execute_no_trans };
 +
neverallow { domain - init } fsck : process transition;
 +
...
 +
neverallow system_server { bluetooth_data_file nfc_data_file shell_data_file app_data_file } : file open;
 +
neverallow system_server dex2oat_exec : file { execute execute_no_trans };
 +
neverallow system_server { dev_type - frp_block_device } : blk_file { append create link unlink relabelfrom rename setattr write open read ioctl lock };
 +
</pre>
 +
 
 +
== setool ==
 +
The <tt>setool</tt> utility is not used during the build process and is intended only to produce entries for the <tt>mac_permissions.xml</tt> file and verify a correctly formated file. It is not supplied in AOSP.
 +
 
 +
Usage:
 +
<pre>
 +
Usage: setool [flags] <--build keys|package OR --policy policyFile> <apk> [ <apk> ]*
  
 
Tool to help build and verify MMAC install policies.
 
Tool to help build and verify MMAC install policies.
  
apks List of apks to analyze, space separated. All supplied apks must
+
    --build      Generate an MMAC style policy stanza with a given --seinfo string.
be absolute paths or relative to --apkdir (which defaults to the current directory).
+
                  The resulting stanza can then be used as an entry in the mac_permissions.xml file.
  
--build Generate an MMAC style policy stanza. The resulting stanza can then be used as an entry in the mac_permissions.xml file.
+
         package  Policy entry that contains the package name inside the signature stanza.
    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.
+
        keys      Print just a signer tag which contains the hex encoded X.509 certs of the app.
 +
 
 +
    --policy     Determine if the apks pass the supplied policy by printing the seinfo tag
 +
                  that would be assigned or null otherwise.
 +
 
 +
      apk        An apk to analyze. All supplied apks must be absolute paths or relative to
 +
                  --apkdir (which defaults to the current directory).
  
 
Flags:
 
Flags:
  --help Prints this message and exits.
+
  --help Prints this message and exits.
  --apkdir Directory to search for supplied apks (default to current directory).
+
  --apkdir Directory to search for supplied apks (default to current directory).
  --verbose Increase the amount of debug statements.
+
  --verbose Increase the amount of debug statements.
  --outfile Dump all output to the given file (defaults to stdout).
+
  --outfile Dump output to the given file (defaults to stdout).
  --seinfo Create an seinfo tag for all generated policy stanzas.
+
  --seinfo Create an seinfo tag for all generated policy stanzas. This is a required flag if using the --build option.
 
</pre>
 
</pre>
  
The following are examples of using <tt>setool</tt>, however, note that they will not produce a valid policy for third party apps.
+
The following examples show the generation and verification process:
 
+
Assuming in Android project directory (<tt>$PREFIX</tt>) and there is a "<tt>demo</tt>" directory present, run <tt>setool</tt> to extract the package info and generate white list entries from a package (any package will suffice for the example):
+
 
<pre>
 
<pre>
setool --seinfo demo --build whitelist demo/SEAndroidDemo.apk > demo/ mac_permissions.xml
+
setool --build package --seinfo service_app --outfile sepolicy/mac_permissions.xml RunIsolatedService.apk
 
</pre>
 
</pre>
  
 
The output will be:
 
The output will be:
 
<pre>
 
<pre>
<signer signature="- key will be here -">
+
<signer signature="- certificate will be here -">
     <package name="com.example.seandroiddemo">
+
     <package name="com.example.runisolatedservice">
         <allow-permission name="android.permission.READ_EXTERNAL_STORAGE" />
+
         <seinfo value="service_app" />
        <allow-permission name="android.permission.SEND_SMS" />
+
        <allow-permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
        <allow-permission name="com.example.seandroiddemo.permission.DEADLY_ACTIVITY" />
+
      <seinfo value="demo" />
+
 
     </package>
 
     </package>
 
</signer>
 
</signer>
 
</pre>
 
</pre>
  
Now assuming a emulator build, add an entry to the <tt>BoardConfig.mk</tt> file <tt>build/target/board/generic/BoardConfig.mk</tt> as follows:
+
Note that for verification via <tt>setool</tt> requires the segment to be included within a correctly formatted <tt>mac_permissions.xml</tt> file (i.e. have the<tt><nowiki> <policy></nowiki></tt> <tt><nowiki></policy></nowiki></tt> tags present:
 
<pre>
 
<pre>
BOARD_SEPOLICY_DIRS := \
+
setool --policy sepolicy/mac_permissions.xml RunIsolatedService.apk
        demo
+
/pre>
  
BOARD_SEPOLICY_UNION := \
+
The output will then be:
        mac_permissions.xml
+
</pre>
+
 
+
Type <tt>make</tt> to rebuild policy changes and run <tt>setool</tt> to check the final concatenated <tt>mac_permissions.xml</tt> policy:
+
 
<pre>
 
<pre>
setool --policy out/target/product/generic/system/etc/security/mac_permissions.xml demo/SEAndroidDemo.apk
+
seinfo tag service_app assigned to ./RunIsolatedService.apk
 
+
Policy passed for com.example.seandroiddemo (demo/SEAndroidDemo.apk).
+
 
</pre>
 
</pre>
  
Line 853: Line 1,400:
 
This utility will take an Android <tt>uid</tt> and convert it to a <tt>username</tt>. The code is a modified version from <tt>bionic/libc/bionic/stubbs.cpp</tt> that converts an Android <tt>uid</tt> to <tt>username</tt>.
 
This utility will take an Android <tt>uid</tt> and convert it to a <tt>username</tt>. The code is a modified version from <tt>bionic/libc/bionic/stubbs.cpp</tt> that converts an Android <tt>uid</tt> to <tt>username</tt>.
  
To compile this assumes that the environment variable <tt>$PREFIX</tt> is set to the Android project directory. This is to allow the header file to be located:
+
To compile this utility:
 
<pre>
 
<pre>
cc -std=gnu99 uid_to_username.c -o uid_to_username -include \
+
cc -std=gnu99 uid_to_username.c -o uid_to_username -include $ANDROID_BUILD_TOP/system/core/include/private/android_filesystem_config.h
$PREFIX/system/core/include/private/android_filesystem_config.h
+
 
</pre>
 
</pre>
  
Line 862: Line 1,408:
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <stdlib.h>
#define CAT_MAPPING_MAX_ID (0x1<<16)
 
  
 
int main(int argc, char **argv)
 
int main(int argc, char **argv)
Line 873: Line 1,418:
 
         exit(1);
 
         exit(1);
 
     }
 
     }
 +
 
     uid = atoi(argv[1]);
 
     uid = atoi(argv[1]);
 
     uid_t appid = uid % AID_USER;
 
     uid_t appid = uid % AID_USER;
 
     uid_t userid = 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) {
 
     if (appid >= AID_ISOLATED_START) {
         printf("u%u_i%u\n", userid, appid - AID_ISOLATED_START);
+
         printf("username: u%u_i%u\n", userid, appid - AID_ISOLATED_START);
 
     } else if (userid == 0 && appid >= AID_SHARED_GID_START) {
 
     } else if (userid == 0 && appid >= AID_SHARED_GID_START) {
         printf("all_a%u\n", appid - AID_SHARED_GID_START);
+
         printf("username: all_a%u\n", appid - AID_SHARED_GID_START);
 
     } else if (appid < AID_APP) {
 
     } else if (appid < AID_APP) {
 
         for (size_t n = 0; n < android_id_count; n++) {
 
         for (size_t n = 0; n < android_id_count; n++) {
 
             if (android_ids[n].aid == appid) {
 
             if (android_ids[n].aid == appid) {
                 printf("u%u_%s\n", userid, android_ids[n].name);
+
                 printf("username: 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);
+
                 printf("Note that only \"%s\" will be shown in 'ps' etc.\n", android_ids[n].name);
 
                 exit(0);
 
                 exit(0);
 
             }
 
             }
Line 897: Line 1,437:
 
         printf("Failed - invalid uid\n");
 
         printf("Failed - invalid uid\n");
 
     } else {
 
     } else {
         printf("u%u_a%u\n", userid, appid - AID_APP);
+
         printf("username: u%u_a%u\n", userid, appid - AID_APP);
 
     }
 
     }
 
     exit(0);
 
     exit(0);
Line 903: Line 1,443:
 
</pre>
 
</pre>
  
 +
 +
{| style="width: 100%;" border="0"
 +
|-
 +
| [[NB_SEforAndroid_1 | '''Previous''']]
 +
| <center>[[NewUsers | '''Home''']]</center>
 +
| <center>[[LibselinuxAPISummary | '''Next''']]</center>
 +
|}
  
  

Latest revision as of 11:41, 17 March 2015

Policy Configuration File Formats

This section details the Android policy configuration file formats with worked examples.

The following files are described:

  • file_contexts
  • seapp_contexts
  • service_contexts
  • property_contexts
  • mac_permissions.xml
  • eops.xml
  • ifw.xml

file_contexts

This file is used to associate default contexts to files for file systems that support extended file attributes. It is used by the file labeling commands such as restorecon.

The Checking File Labels section describes how changes in this file are detected.

The build process supports additional file_contexts files allowing devices to specify their entries as described in the Processing Device Policy section.

Each line within the file consists of the following:

pathname_regexp [file_type] security_context

Where:

pathname_regexp An entry that defines the pathname that may be in the form of a regular expression (see the example file_contexts file below).
file_type One of the following optional file_type entries (note if blank means "match all file types"):
'-b' - Block Device '-c' - Character Device
'-d' - Directory '-p' - Named Pipe (FIFO)
'-l' - Symbolic Link '-s' - Socket File
'--' - Ordinary file

This entry equates to the file mode and also the file related object class (e.g. S_IFSOCK = sock_file class).

security_context This entry can be either:
  • The security context that will be assigned to the file.
  • A value of <<none>> that states matching files should not be re-labeled.


Example entries:

###########################################
# Root
/u:object_r:rootfs:s0

# Data files
/adb_keys       u:object_r:adb_keys_file:s0
/default\.prop  u:object_r:rootfs:s0
/fstab\..*      u:object_r:rootfs:s0
/init\..*       u:object_r:rootfs:s0
/res(/.*)?      u:object_r:rootfs:s0
/ueventd\..*    u:object_r:rootfs:s0
...
##########################
# Devices
#
/dev(/.*)?        u:object_r:device:s0
/dev/akm8973.*    u:object_r:sensors_device:s0
/dev/accelerometer  u:object_r:sensors_device:s0
/dev/adf[0-9]*      u:object_r:graphics_device:s0
/dev/adf-interface[0-9]*\.[0-9]*       u:object_r:graphics_device:s0
/dev/adf-overlay-engine[0-9]*\.[0-9]*  u:object_r:graphics_device:s0
...
/dev/socket/adbd        u:object_r:adbd_socket:s0
/dev/socket/dnsproxyd   u:object_r:dnsproxyd_socket:s0
/dev/socket/dumpstate   u:object_r:dumpstate_socket:s0
...
#############################
# System files
#
/system(/.*)?       u:object_r:system_file:s0
/system/bin/sh  --  u:object_r:shell_exec:s0
/system/bin/run-as  --  u:object_r:runas_exec:s0

#############################
# asec containers
/mnt/asec(/.*)?           u:object_r:asec_apk_file:s0
/mnt/asec/[^/]+/res\.zip  u:object_r:asec_public_file:s0
/mnt/asec/[^/]+/lib(/.*)? u:object_r:asec_public_file:s0
/data/app-asec(/.*)?      u:object_r:asec_image_file:s0

These are example entries from device/asus/flo/sepolicy/file_contexts, note the 'by-name' entry. This is resolved by ueventd as explained in the following commit:

https://android.googlesource.com/platform/system/core/+/b0ab94b7d5a888f0b6920b156e5c6a075fa0741a
# efs block labeling
/dev/block/platform/msm_sdcc\.1/by-name/m9kefs[123c] u:object_r:efs_block_device:s0
# Root block labeling
/dev/block/mmcblk0 u:object_r:root_block_device:s0
# modemst1, modemst2, fsg, ssd labeling
/dev/block/platform/msm_sdcc\.1/by-name/modemst[12] u:object_r:modem_block_device:s0
/dev/block/platform/msm_sdcc\.1/by-name/fsg         u:object_r:modem_block_device:s0
/dev/block/platform/msm_sdcc\.1/by-name/ssd         u:object_r:modem_block_device:s0

It is also worth noting that the 'by-name' (or 'by-num') entry can exist in fstab files as shown in this example taken from device/asus/flo/fstab.flo:

/dev/block/platform/msm_sdcc.1/by-name/system   /system ext4 ro,barrier=1 wait
/dev/block/platform/msm_sdcc.1/by-name/userdata /data   ext4

seapp_contexts

This file is loaded and sorted into memory using the precedence rules explained below on first use by of one of the following Android libselinux functions:

  • selinux_android_setcontext - Computes process security contexts.
  • selinux_android_setfilecon - Computes file/directory security contexts.

The Checking File Labels section describes how changes in this file are detected.

The build process supports additional seapp_contexts files allowing devices to specify their entries as described in the Processing Device Policy section.

The following sections will show:

  1. The default external/sepolicy/seapp_contexts file entries.
  2. A description of the seapp_contexts entries and their usage.
  3. A brief description of how a context is computed using either the selinux_android_setcontext or selinux_android_ setfilecon function using the seapp_contexts file entries.
  4. Examples of computed domain and directory contexts for various apps.

Default Entries

The default Android external/sepolicy/seapp_contexts file contains the following entries:

isSystemServer=true domain=system_server
user=system domain=system_app type=system_app_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=shared_relro domain=shared_relro
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app domain=untrusted_app type=app_data_file levelFrom=user

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)
isOwner (boolean)
user (string)
seinfo (string)
name (string) - A package name e.g. com.example.demo
path (string) - A path name (added to ensure correct labeling of some files).

Notes:

isSystemServer=true can only be used once.
An unspecified isSystemServer defaults to false.
isOwner=true will only match for owner/primary user.
isOwner=false will only match for secondary users.
If unspecified, the entry can match either case.
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 isOwner= before unspecified isOwner=boolean.
3) Specified user= string before unspecified user= string.
4) Fixed user= string before user= prefix (i.e. ending in *).
5) Longer user= prefix before shorter user= prefix.
6) Specified seinfo= string before unspecified seinfo= string.
7) Specified name= string before unspecified name= string.
8) Specified path= string before unspecified path= 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)

Notes:

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 Context

This section explains the process to compute a context using parameters supplied by the selinux_android_setcontext, selinux_android_setfilecon, selinux_android_restorecon and selinux_android_restorecon_pkgdir functions plus the precedence sorted contents of the seapp_contexts file, some examples are then shown.

The context is computed first by converting the uid parameter to a string that is used to match the user component in the seapp_contexts entry as follows:

  1. If an Android system service, the uid parameter is converted to a username string via an internal Android table (e.g. "radio", "system").
  2. If an isolated service the _isolated string is used as the username.
  3. For any other app or service _app string is used as the username.

Then cycling through each precedence sorted seapp_contexts entry, check each component as follows until a match is found or generate an error log entry:

  • The isSystemServer component is matched against the isSystemServer parameter. If a match or isSystemServer not present check remaining components, else skip entry.
  • The isOwner boolean determines whether the remaining components should be checked or skip this entry. The rules are:
    • If isOwner not present then check remaining components.
    • If set true and the uid computes to the owner or primary user then check remaining components, else skip this entry.
    • If set false and the uid computes to a secondary user then check remaining components, else skip this entry.
  • The computed username is matched against the user component. If a match or user not present check remaining components, else skip entry.
  • The seinfo component is matched against the seinfo parameter. If a match or seinfo not present check remaining components, else skip entry.
  • The name component is matched against the pkgname parameter. If a match or name not present check remaining components, else skip entry.
  • The path component is matched against a computed path of a file having its context restored via one of the restorecon functions. If a match or path not present check remaining components, else skip entry.
  • The domain component is used to set the process context for the selinux_android_setcontext function and must match a type declared in the policy. If domain not present skip this entry.
  • The type component is used to set the file context for the selinux_android_setfilecon function and must match a type declared in the policy. If type not present skip this entry.
  • The levelFrom and level components if present will be used to determine the level component of the security context as follows:
    • if levelFrom=none then use current level.
    • else if levelFrom=app then compute a category pair based on a derived app id with a starting base of c512,c768 base.
    • else if levelFrom=user then compute a category pair based on a derived user id with a starting base of c0,c256 base.
    • else if levelFrom=all then compute a category pair based on a derived app id with a starting base of c512,c768 base, and also compute another category pair based on a derived user id with a starting base of c0,c256 base.
    • else if level has a value use this as the context level.

The overall objective is that the computed levels should never be the same for different apps, users, or a combination of both. By encoding each ID as a category pair, up to 2^16 app IDs and up to 2^16 user IDs within the 1024 categories can be represented, including the levelFrom=all or mixed usage of levelFrom=app and levelFrom=user.

If a valid entry is found, then:

  1. If a context for the selinux_android_setcontext function has been computed, it is validated against policy, if correct setcon(3) is used to set the process context.
  2. If a context for selinux_android_setfilecon, selinux_android_restorecon or selinux_android_restorecon_pkgdir functions have been computed, it is validated against policy, if correct setfilecon(3) or lsetfilecon(3) are used to set the context for labeling the file.

If a valid entry is not found an error is generated in the log currently formatted as follows:

seapp_context_lookup: No match for app with uid uid, seinfo seinfo, name pkgname

Computing Process Context Examples

The following is an example taken as the system server is loaded:

selinux_android_setcontext() parameters:
    uid 1000
    isSystemServer true
    seinfo null
    pkgname null

seapp_contexts lookup parameters:
    uid 1000
    isSystemServer true
    seinfo null
    pkgname null
    path null

Matching seapp_contexts entry:
    isSystemServer=true domain=system_server

Outputs:
    domain system_server
    level  s0

Computed context = u:r:system_server:s0
username computed from uid = system

Result using ps -Z command:
    LABEL                USER   PID PPID NAME
    u:r:system_server:s0 system 836 63   system_server

This is the ’radio’ application that is part of the platform:

selinux_android_setcontext() parameters:
    uid 1001
    isSystemServer false
    seinfo platform
    pkgname com.android.phone

seapp_contexts lookup parameters:
    uid 1001 (computes user=radio entry)
    isSystemServer false
    seinfo platform
    pkgname com.android.phone
    path null

Matching seapp_contexts entry:
    user=radio domain=radio type=radio_data_file

Outputs:
    domain radio
    level  s0

Computed context = u:r:radio:s0
username computed from uid = radio

Result using ps -Z command:
    LABEL        USER  PID PPID NAME
    u:r:radio:s0 radio 619 62   com.android.phone

This is the 'SEAndroid Admin Manager' application that is part of the SEAndroid release, however it is treated as an untrusted app (it is installed as a privileged app):

selinux_android_setcontext() parameters:
    uid 10013
    isSystemServer false
    seinfo default
    pkgname com.android.seandroid_admin

seapp_contexts lookup parameters:
    isSystemServer false
    uid 10013 (computes user=_app entry) 
    seinfo default
    pkgname com.android.seandroid_admin
    path null

Matching seapp_contexts entry:
    user=_app domain=untrusted_app type=app_data_file levelFrom=user

Outputs:
    domain untrusted_app
    level  s0:c512,c768

Computed context = u:r:untrusted_app:s0:c512,c768
username computed from uid = u0_a13

Result using ps -Z command:
    LABEL                          USER   PID PPID NAME
    u:r:untrusted_app:s0:c512,c768 u0_a13 827 45   com.android.seandroid_admin

This is a third party app (com.example.runisolatedservice) to run an isolated service that has been installed as a privileged app (com.se4android.isolatedservice):

selinux_android_setcontext() parameters:
    uid 10054
    isSystemServer false
    seinfo default
    pkgname com.example.runisolatedservice

seapp_contexts lookup parameters:
    uid 10054 (computes user=_app entry)
    isSystemServer false
    seinfo default
    pkgname com.example.runisolatedservice
    path null

Matching seapp_contexts entry:
    user=_app domain=untrusted_app type=app_data_file levelFrom=user

Outputs:
    domain untrusted_app
    level  s0:c512,c768

Computed context = u:r:untrusted_app:s0:c512,c768
username computed from uid = u0_a54

Result using ps -Z command:
    LABEL USER                     PID    PPID NAME
    u:r:untrusted_app:s0:c512,c768 u0_a54 1138 64 com.example.runisolatedservice

This is the isolated service installed as a privileged app (com.se4android.isolatedservice):

selinux_android_setcontext() parameters:
    uid 99000
    isSystemServer false
    seinfo default
    pkgname com.se4android.isolatedservice

seapp_contexts lookup parameters:
    uid 99000 (computes user=_isolated entry)
    isSystemServer false
    seinfo default
    pkgname com.se4android.isolatedservice
    path null

Matching seapp_contexts entry:
    user=_isolated domain=isolated_app levelFrom=user
    Note that uid's 99000-99999 are reserved for isolated services - see:
        system/core/include/private/android_filesystem_config.h

Outputs:
    domain isolated_app
    level  s0:c512,c768

Computed context = u:r:isolated_app:s0:c512,c768
username computed from uid = u0_i0

Result using ps -Z command:
    LABEL                         USER  PID  PPID NAME
    u:r:isolated_app:s0:c512,c768 u0_i0 1140 62   com.se4android.isolatedservice

Computing File Context Example

The following example is from the third party isolated app:

selinux_android_setfilecon() parameters:
    pkgdir /data/data/com.example.runisolatedservice
    pkgname com.example.runisolatedservice
    seinfo default
    uid 10046

seapp_contexts lookup parameters:
    uid 10046 (computes user=_app entry)
    isSystemServer false
    seinfo default
    pkgname com.example.runisolatedservice
    path null

Matching seapp_contexts entry:
    user=_app domain=untrusted_app type=app_data_file levelFrom=user

Outputs:
    type  app_data_file
    level s0:c512,c768

Computed context = u:object_r:app_data_file:s0:c512,c768
username computed from uid = u0_a46

Result from /data/data directory using ls -Z command:
    drwxr-x--x u0_a46 u0_a46 u:object_r:app_data_file:s0:c512,c768 com.example.runisolatedservice

property_contexts

This file holds property service keys and their contexts that are matched against property names using selabel_lookup(3). The returned context will then be used as the target context as described in the example below to determine whether the property is allowed or denied (see system/core/init/property_service.c and init.c).

The build process supports additional property_contexts files allowing devices to specify their entries as described in the Processing Device 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 based on matching the property_key.

Example:

Use adb to reload the SELinux policy:

adb shell su 0 setprop selinux.reload_policy 1

Sample property_contexts file entries are:

# property_key        context to be applied on match
net.rmnet             u:object_r:net_radio_prop:s0
net.gprs              u:object_r:net_radio_prop:s0
net.ppp               u:object_r:net_radio_prop:s0
net.qmi               u:object_r:net_radio_prop:s0
net.lte               u:object_r:net_radio_prop:s0
net.cdma              u:object_r:net_radio_prop:s0
net.dns               u:object_r:net_radio_prop:s0
sys.usb.config        u:object_r:system_radio_prop:s0
ril.                  u:object_r:radio_prop:s0
gsm.                  u:object_r:radio_prop:s0
persist.radio         u:object_r:radio_prop:s0

debug.                u:object_r:debug_prop:s0
debug.db.             u:object_r:debuggerd_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.logd.         u:object_r:logd_prop:s0
persist.sys.          u:object_r:system_prop:s0
persist.service.      u:object_r:system_prop:s0
persist.service.bdroid. u:object_r:bluetooth_prop:s0
persist.security.     u:object_r:system_prop:s0

# selinux non-persistent properties
selinux.              u:object_r:security_prop:s0

# default property context (* is wild card match)
*                     u:object_r:default_prop:s0

The property service will call selabel_lookup with parameters consisting of the handle passed from selabel_open, a buffer to hold the returned context, and the object name "selinux.reload_policy" to look-up (the final parameter is not used):

selabel_lookup(handle, &context, "selinux.reload_policy", 1);

The following context will be returned as the look-up process will search for a match based on the length of the property_key (and will therefore match against "selinux."):

u:object_r:security_prop:s0

The property service will then validate whether the service has permission by issuing an selinux_check_access(3) call with the following parameters:

source context: u:r:su:s0
target context: u:object_r:security_prop:s0
class:          property_service
permission:     set

The policy would then decide whether to allow or deny the property request. Using the sepolicy-check tool will show that this will be denied by the current policy (a dontaudit rule is in the policy, however su runs permissive anyway):

sepolicy-check -s su -t security_prop -c property_service -p set -P out/target/product/generic/root/sepolicy
echo $?
1

service_contexts

This file holds binder service keys and their contexts that are matched against binder object names using selabel_lookup(3). The returned context will then be used as the target context as described in the example below to determine whether the binder service is allowed or denied (see frameworks/native/cmds/servicemanager/servicemanager.c).

The build process supports additional service_contexts files allowing devices to specify their 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 based on matching the service_key.

Example:

The healthd process wants to start a binder service "batterypropreg" (see frameworks/base/services/java/com/android/server/BatteryService.java).

Sample service_contexts file entries are:

# service_key          context to be applied on match
batteryproperties      u:object_r:healthd_service:s0
batterystats           u:object_r:system_server_service:s0
battery                u:object_r:system_server_service:s0
 
# default service context (* is wild card match)
*                      u:object_r:default_android_service:s0

The service manager will call selabel_lookup with parameters consisting of the handle passed from selabel_open, a buffer to hold the returned context, and the object name "batterypropreg" to look-up (the final parameter is not used):

selabel_lookup(handle, &context, "batterypropreg", 1);

The following context will be returned as the look-up process will search for a match based on the length of the service_key (and will therefore match against "battery"):

u:object_r:system_server_service:s0

The service manager will then validate whether the service has permission by issuing an selinux_check_access(3) call with the following parameters:

source context: u:r:healthd:s0
target context: u:object_r:system_server_service:s0
class:          service_manager
permission:     add

The policy would then decide whether to allow or deny the service. Using the sepolicy-check tool will show that this will be allowed by the current policy:

sepolicy-check -s healthd -t system_server_service \
-c service_manager -p add \
-P out/target/product/generic/root/sepolicy
Match found!

mac_permissions.xml

The mac_permissions.xml file is used to configure Run/Install-time MMAC policy and provides x.509 certificate to seinfo string mapping so that Zygote spawns an app in the correct domain. See the Computing a Context section for how this is achieved using information also contained in the seapp_contexts file (AOSP and SEAndroid).

An example AOSP mac_permissions.xml file that 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>

    <!-- All other keys -->
    <default>
        <seinfo value="default" />
    </default>

</policy>


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 as shown that allows the key to be extracted from a pem file as discussed in the insertkeys.py section. If a base16 key is required, it can be extracted from a package using the post_process_mac_perms and setool utilities.

The build process supports additional mac_permissions.xml files allowing devices to specify their entries as described in the Processing Device Policy section. An example SEAndroid test device mac_permissions.xml file is:

<?xml version="1.0" encoding="utf-8"?>

<policy>

    <!-- NET_APPS key and seinfo for SE4A-NetClient & SE4A-NetServer apps. -->
    <signer signature="@NET_APPS" >
        <package name="com.se4android.netclient" >
            <seinfo value="netclient" />
        </package>
        <package name="com.se4android.netserver" >
            <seinfo value="netserver" />
        </package>
    </signer>

</policy>

Policy Rules

The following rules have been extracted from the AOSP mac_permissions.xml file with the one SEAndroid addition noted:

  • A signature is a hex encoded X.509 certificate or a tag defined in keys.conf and is required for each signer tag.
  • A signer tag may contain a seinfo tag and multiple package stanzas.
  • A default tag is allowed that can contain policy for all apps not signed with a previously listed cert. It may not contain any inner package stanzas.
  • Each signer/default/package tag is allowed to contain one seinfo tag. This tag represents additional info that each app can use in setting a SELinux security context on the eventual process.
  • When a package is installed the following logic is used to determine what seinfo value, if any, is assigned:
    • All signatures used to sign the app are checked first.
    • If a signer stanza has inner package stanzas, those stanza will be checked to try and match the package name of the app. If the package name matches then that seinfo tag is used. If no inner package matches then the outer seinfo tag is assigned.
    • The default tag is consulted last if needed.
    • If none of the cases apply then the app is denied install on the device. NOTE: This case only applies to SEAndroid.

eops.xml

The following text has been taken from the SEAndroid /external/sepolicy/eops.xml file (so check if any changes) with a few minor additions (there is also a simple example in the EOps Example section section).

EOps (enterprise operations) is a security extension to the App Operations (AppOps) feature already present on Android 4.3+ devices. AppOps lets users fine tune certain functionality requested by apps by allowing the user to toggle these access rights.

EOps seeks to provide an extension whereby a hard coded set of rules explicitly denies certain access rights to groups of installed apps. This feature will allow an enterprise like control over certain operations. EOps is not a front-end for SELinux which somehow ties app permissions to SELinux contexts. Rather, it is an extension of the middleware MAC (MMAC) controls that currently exist on Android 4.3+ devices. EOps uses the seinfo labels that are already assigned to apps upon install.

The list of viable op tag names can be found in frameworks/base/core/java/android/app/AppOpsManager.java. Just use the string version of each op without the OP_ prefix in your policy tags. These are the current 48 entries (March '15):

COARSE_LOCATION FINE_LOCATION GPS
VIBRATE READ_CONTACTS WRITE_CONTACTS
READ_CALL_LOG WRITE_CALL_LOG READ_CALENDAR
WRITE_CALENDAR WIFI_SCAN POST_NOTIFICATION
NEIGHBORING_CELLS CALL_PHONE READ_SMS
WRITE_SMS RECEIVE_SMS RECEIVE_EMERGECY_SMS
RECEIVE_MMS RECEIVE_WAP_PUSH SEND_SMS
READ_ICC_SMS WRITE_ICC_SMS WRITE_SETTINGS
SYSTEM_ALERT_WINDOW ACCESS_NOTIFICATIONS CAMERA
RECORD_AUDIO PLAY_AUDIO READ_CLIPBOARD
WRITE_CLIPBOARD TAKE_MEDIA_BUTTONS TAKE_AUDIO_FOCUS
AUDIO_MASTER_VOLUME AUDIO_VOICE_VOLUME AUDIO_RING_VOLUME
AUDIO_MEDIA_VOLUME AUDIO_ALARM_VOLUME AUDIO_NOTIFICATION_VOLUME
AUDIO_BLUETOOTH_VOLUME WAKE_LOCK MONITOR_LOCATION
MONITOR_HIGH_POWER_LOCATION GET_USAGE_STATS MUTE_MICROPHONE
TOAST_WINDOW PROJECT_MEDIA ACTIVATE_VPN

All operations listed in the policy will have a mode of ignored. This means that empty data sets are returned to the caller when an operation is requested. This shadow data will then allow certain apps to presumably still operate. However, AOSP currently is not constructed to return these empty data sets and therefore acts as if ignored operations are completely denied (blocked). Because of this some apps might crash or behave oddly if you apply certain eops policy. In addition, while AOSP seems to have hooked the proper places to check operations against policy some of those hooks fail to follow through with the denial and still allow the operation to occur. Because of this, EOps will also fail to make those distinctions and likewise fail to enforce certain operations. Once the AOSP pieces are in place to return legitimate fake data and enforce all operations then of course eops, by its design, will also do the same.

So, as long as AppOps is beta so too will EOps.

A debug tag is also allowed which flips on the global debugging log functionality inside AppOps.

Each stanza is grouped according to the seinfo tag that is assigned during install and thus creates a dependency with the mac_permissions.xml file. Each seinfo tag can then include any number of op tags. By including the op(s) you are simply removing that operation from working for all apps that have been installed with the listed seinfo label. These operations are restricted regardless of what any user controlled app ops policy may say. Any op not listed is therefore still subject to user control as normal.

Lastly, there is no permissive mode for EOps. Once a policy is in place all ops listed are enforced.

The following is an example eops.xml policy file that will stop the camera being used by any system or default app. The file installation is shown in the Build Bundle Tools - buildeopbundle section:

<?xml version="1.0"?>
<app-ops>

    <debug/>

    <seinfo name="default">
        <op name="CAMERA"/>
    </seinfo>

    <seinfo name="system">
        <op name="CAMERA"/>
    </seinfo>

</app-ops>

ifw.xml

The example external/sepolicy/ifw.xml file has some comments regarding the tags, there is also an overview at http://www.cis.syr.edu/~wedu/android/IntentFirewall/.

The following is an example ifw.xml policy file that will stop the DemoIsolatedService being used by any app other than system apps or apps with the same signature. The file installation is shown in the Build Bundle Tools - buildifwbundle section:

<?xml version="1.0"?>

<rules>

    <!-- This will stop any app that is not a system app or
         does not have a matching signature from running the
         DemoIsolatedService service
    -->

    <service log="true" block="true">
        <not><sender type="system|signature"/></not><
        <intent-filter />
            <component-filter name="com.se4android.isolatedservice/.DemoIsolatedService"/>
    </service>

</rules>

The events will be in the event log under the 'ifw_intent_matched' tag, for example:

adb logcat -b events
...
...
I/ifw_intent_matched( 390):[2,com.se4android.isolatedservice/.DemoIsolatedService,10058,1,NULL,NULL,NULL,NULL,0]
...

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, property_contexts and service_contexts files against policy. If validation fails checkfc will exit with an error.

Usage:

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 (note: no -p parameter):

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.

Usage:

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
    -s - enable strict checking of duplicates. This causes the program to exit on a duplicate entry with a non-zero exit status
    -v - enable verbose debugging informations
    -p policy file - specify policy file for strict checking of output selectors against the policy
    -o output file - specify output file, default is stdout

An example command with output to stdout is:

checkseapp -p out/target/product/se4a_device/root/sepolicy out/target/product/se4a_device/root/seapp_contexts

isSystemServer=true domain=system_server
user=system domain=system_app type=system_app_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=shared_relro domain=shared_relro
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app levelFrom=user
user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
user=_app domain=untrusted_app type=app_data_file levelFrom=user
user=_app seinfo=netclient domain=netclient_app type=net_apps_log_file levelFrom=app
user=_app seinfo=netserver domain=netserver_app type=net_apps_log_file levelFrom=app

insertkeys.py

The insertkeys.py utility is used during the build process to insert signing keys into the mac_permissions.xml file. 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 File section.

insertkeys.py generates base16 encodings from the base64 pem files as this is required by the Android Package Manager Service. The resulting mac_permissions.xml file will also be stripped of comments and whitespace.

Usage:

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

keys.conf File

The keys.conf file is used by insertkeys.py for mapping the "@..." tags in mac_permissions.xml, mmac_types.xml and content_provider.xml signature entries with public keys found in pem files. The configuration file can be used in the BOARD_SEPOLICY_UNION variable 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 is as follows:

#
# Maps an arbitrary tag [TAGNAME] with the string contents found in
# TARGET_BUILD_VARIANT. 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. Typcially this is user, eng, and userdebug. Another
# option is to use ALL which will match ANY TARGET_BUILD_VARIANT string.
#

[@PLATFORM]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/platform.x509.pem

[@MEDIA]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/media.x509.pem

[@SHARED]
ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/shared.x509.pem

# Example of ALL TARGET_BUILD_VARIANTS
[@RELEASE]
ENG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
USER : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem
USERDEBUG : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testkey.x509.pem

The following is an example entry that will use a device specific key during the build process:

[@NET_APPS]
ALL : $ANDROID_BUILD_TOP/device/demo_vendor/se4a_device/security/net_apps.x509.pem

Build Bundle Tools

The following tools will produce an Android "bundle" for updating MAC/MMAC policy within a zip file suitable for installation by the SEAdmin app. SEAdmin is currently hard-coded to look for these zip files in the SD Card device (/sdcard/).

The buildsebundle section also shows how a policy can be updated by broadcasting an intent instead of using SEAdmin.

buildsebundle

The buildsebundle tool will produce an Android "bundle" for updating the core SE for Android policy within an selinux_bundle.zip file, suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the Using an Intent Example section.

To be able to build the bundle the following mandatory files are required:

selinux_version, sepolicy, file_contexts, seapp_contexts, property_contexts, service_contexts, mac_permissions.xml

Usage:

usage: buildsebundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
    [-h] -- <selinux_version> <file_contexts> <property_contexts> \
    <sepolicy> <seapp_contexts> <service_contexts> <mac_permissions.xml>

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

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 SHA-512 hash of the bundle to replace. Defaults to 'NONE'.

The following is an example where a new policy has been built with all required files. The wildcard can be used as buildsebundle will always use the mandatory list:

buildsebundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 \
-v 3 -- $ANDROID_BUILD_TOP/device/demo_device/se4a_device/new_sepolicy/*

adb push selinux_bundle.zip /sdcard/

Once built, the bundle is pushed to the SD card and SEAdmin is used to update the policy (note that SEAdmin only reads the bundle from /sdcard).

Using an Intent Example

This example shows how to update a policy by broadcasting an intent in the same way as SEAdmin.

Extract the selinux_bundle files from the selinux_bundle.zip file:

unzip selinux_bundle.zip
Archive: selinux_bundle.zip
    inflating: update_bundle 
    inflating: update_bundle_metadata

The two files contain:

update_bundle - Contains hex encoded policy files to be installed.
update_bundle_metadata - This is used by SEAdmin to form the intent and contains a hash of the bundle to replace or "NONE", the signature of the update_bundle and the bundle version (in this case "3"). Example contents are:
NONE:I6E0cZ8WbF6kJWkDozJCfckw5xuZhXuE0iqrbszsxhi7S4Z3DrR7RiH/aomRQxeskvMv9B/+G7JXfxFAQlV1CWZihnefkHGnei4atKnBLPK/g3gmf0Wb0jjizc4yb4uvu/XQAZvybKcsTvTiegfqTHMFWPGKgoq97RKAjk2kT2fa3liArylTrLl7OfRtKq6mNjQNnfVrte9e/aJptiAmOwDNdQydfRwhewrKPE6rM+YNuHJaJ+h28dNecQtCn9TabTxn8I1G+10d5/wmjjgXq6MdfEMQZ++H4ZIaL4bTdUOQVdFeMsnFLA3hjLGf3BXpHmG84s7iDO158V0kbXikzA==:3

Push the update_bundle to the device:

adb push update_bundle /data/update_bundle

Build an intent to broadcast via adb by including the bundle location, with the hash, signature and version from the update_bundle_metadata as follows:

adb shell am broadcast -a android.intent.action.UPDATE_SEPOLICY -e "CONTENT_PATH" "/data/update_bundle" -e "REQUIRED_HASH" "NONE" -e "SIGNATURE" "I6E0cZ8WbF6kJWkDozJCfckw5xuZhXuE0iqrbszsxhi7S4Z3DrR7RiH/aomRQxeskvMv9B/+G7JXfxFAQlV1CWZihnefkHGnei4atKnBLPK/g3gmf0Wb0jjizc4yb4uvu/XQAZvybKcsTvTiegfqTHMFWPGKgoq97RKAjk2kT2fa3liArylTrLl7OfRtKq6mNjQNnfVrte9e/aJptiAmOwDNdQydfRwhewrKPE6rM+YNuHJaJ+h28dNecQtCn9TabTxn8I1G+10d5/wmjjgXq6MdfEMQZ++H4ZIaL4bTdUOQVdFeMsnFLA3hjLGf3BXpHmG84s7iDO158V0kbXikzA==" -e "VERSION" "3"

When the intent has been broadcast there will be a response, however that does not indicate that the policy was updated, just that the intent was broadcast:

Broadcasting: Intent { act=android.intent.action.UPDATE_SEPOLICY (has extras) }
Broadcast completed: result=0

logcat should show whether it was successful:

I/ConfigUpdateInstallReceiver( 908): Found new update, installing...
I/ConfigUpdateInstallReceiver( 908): Installation successful
I/SELinuxPolicyInstallReceiver( 908): Applying SELinux policy

If the update failed because of versioning then an error is given (however if signature incorrect fails silently).

The following show various policy information after the third update:

adb shell ls -l /data/security/current
lrwxrwxrwx system system 2014-07-19 10:41 current -> /data/security/contexts
adb shell ls -l /data/security/contexts

-rw-r--r-- system system 10512 2014-07-19 10:41 file_contexts
-rw-r--r-- system system 10656 2014-07-19 09:01 file_contexts_backup
-rw-r--r-- system system 4203 2014-07-19 10:41 mac_permissions.xml
-rw-r--r-- system system 4203 2014-07-19 09:01 mac_permissions.xml_backup
-rw-r--r-- system system 2549 2014-07-19 10:41 property_contexts
-rw-r--r-- system system 2549 2014-07-19 09:01 property_contexts_backup
-rw-r--r-- system system 641 2014-07-19 10:41 seapp_contexts
-rw-r--r-- system system 641 2014-07-19 09:01 seapp_contexts_backup
-rw-r--r-- system system 78 2014-07-19 10:41 selinux_version
-rw-r--r-- system system 78 2014-07-19 09:01 selinux_version_backup
-rw-r--r-- system system 115831 2014-07-19 10:41 sepolicy
-rw-r--r-- system system 116438 2014-07-19 09:01 sepolicy_backup
-rw-r--r-- system system 7748 2014-07-19 10:41 service_contexts
-rw-r--r-- system system 7748 2014-07-19 09:01 service_contexts_backup
adb shell ls -l /data/security

drwx------ system system 2014-07-19 10:41 bundle
drwx------ system system 2014-07-19 10:41 contexts
lrwxrwxrwx system system 2014-07-19 10:41 current ->/data/security/contexts
drwx------ system system 2014-07-19 10:37 eops
adb shell ls -l /data/security/bundle

drwx------ system system 2014-07-19 10:41 metadata
-rw-r--r-- system system 191271 2014-07-19 10:41 sepolicy_bundle
adb shell ls -l /data/security/bundle/metadata

-rw-r--r-- system system 1 2014-07-19 10:41 version
adb shell cat /data/security/bundle/metadata/version
3

The loaded policy can be extracted from the device if required by:

adb pull /sys/fs/selinux/policy sepolicy-v3

buildeopbundle

The buildeopbundle tool will produce an Android "bundle" for updating the Enterprise Operations policy within an eops_bundle.zip file suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the Using an Intent Example section.

To be able to build the bundle an eops.xml file is required.

Usage:

usage: buildeopbundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
[-h] -- <eops.xml>

This script builds a eops 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 a key size of at least 1024 or greater. The bundle requires that the eops.xml file be included and with that exact basename. The built bundle will be written to eop_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   SHA-512 hash of the bundle to replace. Defaults to 'NONE'.

Eops Example

The following is an example where a new eops.xml file has been produced, bundled, then pushed to the SD card. SEAdmin is then used to update the policy (note that SEAdmin only reads the bundle from /sdcard):

buildeopbundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -v 1 -- eops.xml

adb push eops_bundle.zip /sdcard/

logcat should show if it was successful:

D/SEAdminConfigUpdateFragment( 904): android.intent.action.UPDATE_EOPS intent being broadcast. Bundle[{CONTENT_PATH=/cache/eops_bundle, SIGNATURE=qZJ8I07MHFTXaII2jhPMooRLzejArUI0qsvkteG9nzEzgzjwyh8RWUaaRil6xrQsPb5g+qWj+nfQCkH7DIEow/WF8S1sTeReS8G/z+hPQi0MHgWGKH0kCIfXn6yqqEri3+Dnolb1vHVuM7t/0mszCvtjqfq5GWbHZc1xYSgMQJXqrhfzSqa2zvO4+7zE0GszfuZXwt9QHci9C1IJ5B50URmmg4TDIuhfISWW9vYkEctwARIyCLhfYiZzIQOwzPj3oSHI1AUWMHxbbpADFzCumZ1WdfpA0txow8rDM+01qkKGtcAsNs8me2FAPz28tckQ9ea6QwAzDCSP3PzQC1Horg==, REQUIRED_HASH=NONE, VERSION=1}]
I/ConfigUpdateInstallReceiver( 395): Couldn't find current metadata, assuming first update
I/ConfigUpdateInstallReceiver( 395): Failed to read current content, assuming first update!
I/ConfigUpdateInstallReceiver( 395): Found new update, installing...
I/ConfigUpdateInstallReceiver( 395): Installation successful
D/AppOps ( 381): Eops policy: system [ CAMERA]
D/AppOps ( 381): Eops policy: default [ CAMERA]

The new file and its supporting metadata are:

adb shell su 0 ls -lR /data/security/eops

/data/security/eops:
-rw-r--r-- system system 189 2014-07-20 14:15 eops.xml
drwx------ system system 2014-07-20 14:15 eops_metadata

/data/security/eops/eops_metadata:
-rw-r--r-- system system 1 2014-07-20 14:15 version

The version number after the update is:

adb shell su 0 cat /data/security/eops/eops_metadata/version
1

Because the Eops policy specified an seinfo of system and the operation CAMERA, if the Camera app is now started it will load however, it will not be possible to take pictures as logcat will show:

D/AppOps ( 381): startOperation: reject #1 for code 26 (26) uid 10026 package com.android.camera2
I/CameraService( 60): Camera 0: Access for "com.android.camera2" has been revoked

buildifwbundle

The buildifwbundle tool will produce an Android "bundle" for updating the Intent Firewall policy within an ifw_bundle.zip file suitable for installation by the SEAdmin app, although it is possible to update using an intent as described in the Using an Intent Example section.

To be able to build the bundle an ifw.xml file is required, although note that the Intent Firewall service will read any file so long as it has the .xml extension.

Usage:

usage: buildifwbundle -k <private key.pk8> [-v <version>] [-r <previous hash>] \
[-h] -- <ifw.xml>

This script builds an intent firewall 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 a key size of at least 1024 or greater. The bundle requires that the ifw.xml file be included and with that exact basename. The built bundle will be written to ifw_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 SHA-512 hash of the bundle to replace. Defaults to 'NONE'.

IFW Example

The following is an example where a new ifw.xml file has been produced, bundled, and then pushed to the SD card. SEAdmin is then used to update the policy (note that SEAdmin only reads the bundle from /sdcard):

buildsifwbundle -k $ANDROID_BUILD_TOP/build/target/product/security/testkey.pk8 -v 1 -- eops.xml

adb push ifw_bundle.zip /sdcard/

logcat should show whether it was successful:

D/SEAdminConfigUpdateFragment( 904): android.intent.action.UPDATE_INTENT_FIREWALL intent being broadcast. Bundle[{CONTENT_PATH=/cache/ifw_bundle, SIGNATURE=tfQONpEZbL1Y6sXj1BY98TO4izK2IyeqO9Hko5tZygE77zry98RGmU5BAAIFs21G9G7WpAcPTR7TGe4LRMpB7SKeZ1Xh+4B+U+30TnHkwXp9HRIgIJcN5Kqiyp/UPAjEJjYmBZk+yM5FLYcMCQS082wfpC9c+gRQcl6AYuSmiynvjgc1d33rtfB7Hd40LF30mBZyyiUJc5YF1ddaITBbL/CCKmFblfBqadZtmCN7xGUIJEHqWPnuEvscatkOLgZa+35ZXfl2WkD/DsGkwocXM9akjD0NJY9WZJpzwAHQPdQFXN6nthrsV8kiC7OUFvK/PKll9oetiyTSEEVH5JlMnA==, REQUIRED_HASH=NONE, VERSION=1}]
I/ConfigUpdateInstallReceiver( 395): Couldn't find current metadata, assuming first update
I/ConfigUpdateInstallReceiver( 395): Failed to read current content, assuming first update!
I/ConfigUpdateInstallReceiver( 395): Found new update, installing...
I/ConfigUpdateInstallReceiver( 395): Installation successful
I/IntentFirewall( 395): Read new rules (A:0 B:0 S:1)

The new file and its supporting metadata are:

adb shell su 0 ls -lR /data/system/ifw

/data/system/ifw:
-rw-r--r-- system system 454 2014-07-20 13:14 ifw.xml
drwx------ system system 2014-07-20 13:14 metadata

/data/system/ifw/metadata:
-rw-r--r-- system system 1 2014-07-20 13:14 gservices.version

The version number after the update is:

adb shell su 0 cat /data/system/ifw/metadata/gservices.version
1

post_process_mac_perms

This tool will modify an existing mac_permissions.xml with additional app certs not already found in that policy. This becomes useful when a directory containing apps is searched and the certs from those apps are added to the policy not already explicitly listed.

There is no make target for this tool (python script), so either move to HOST_EXECUTABLE or execute directly (e.g. $PREFIX/external/sepolicy/tools/post_process_mac_perms).

Usage:

post_process_mac_perms [-h] -s SEINFO -d DIR -f POLICY

   -s SEINFO, --seinfo SEINFO seinfo tag for each generated stanza
   -d DIR, --dir DIR Directory to search for apks
   -f POLICY, --file POLICY mac_permissions.xml policy file

Example:

post_process_mac_perms -s netapps -d ./APK -f mac_permissions.xml

Before:

<?xml version="1.0" encoding="utf-8"?>
<policy>
    <signer signature="- certificate here -" ><seinfo value="platform"/></signer>
    <default><seinfo value="default"/></default>
</policy>

After:

<?xml version="1.0" encoding="utf-8"?>
<policy>
    <signer signature="- certificate here -" ><seinfo value="platform"/></signer>
    <default><seinfo value="default"/></default>
    <signer signature="- certificate here -"><seinfo value="netapps"/></signer>
</policy>

sepolicy_check

A tool for auditing a sepolicy file for any allow rule that grants a given permission.

Usage:

sepolicy-check -s <domain> -t <type> -c <class> -p <permission> 
-P out/target/product/<board>/root/sepolicy

The output will be "Match found!" or silent if not. sepolicy_check will return 0 for found, 1 for not found and -1 for an error.

Examples:

 sepolicy-check -s healthd -t system_server_service \
  -c service_manager -p add \
  -P  out/target/product/generic/root/sepolicy
  Match found!
<tt>sepolicy-check -s su -t security_prop -c property_service \</tt>
 -p set -P out/target/product/generic/root/sepolicy
  echo $?
  1

sepolicy-analyze

This is the text from the external/sepolicy/tools/README that describes the tool for performing various kinds of analysis on a sepolicy file. The analysis currently supported includes:

Type Equivalence

sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -e

Display all type pairs that are "equivalent", i.e. they are identical with respect to allow rules, including indirect allow rules via attributes and default-enabled conditional rules (i.e. default boolean values yield a true conditional expression).

Equivalent types are candidates for being coalesced into a single type. However, there may be legitimate reasons for them to remain separate, for example: - the types may differ in a respect not included in the current analysis, such as default-disabled conditional rules, audit-related rules (auditallow or dontaudit), default type transitions, or constraints (e.g. mls), or - the current policy may be overly permissive with respect to one or the other of the types and thus the correct action may be to tighten access to one or the other rather than coalescing them together, or - the domains that would in fact have different accesses to the types may not yet be defined or may be unconfined in the policy you are analyzing.

Example output:

sepolicy-analyze out/target/product/generic/root/sepolicy typecmp -e

Types adbd_socket and mdns_socket are equivalent.
Types wifip2p_service and network_score_service are equivalent.
Types wifip2p_service and registry_service are equivalent.
...
Types rild_debug_socket and init_tmpfs are equivalent.
Types ram_device and vcs_device are equivalent.
Types ram_device and uio_device are equivalent.
..
Types loop_device and vold_device are equivalent.

Type Difference

sepolicy-analyze out/target/product/<board>/root/sepolicy typecmp -d

Display type pairs that differ and the first difference found between the two types. This may be used in looking for similar types that are not equivalent but may be candidates for coalescing.

Example output:

sepolicy-analyze out/target/product/generic/root/sepolicy typecmp -d

Types adbd_socket and functionfs differ, starting with:
    allow adbd_socket rootfs:filesystem {  associate };
    allow functionfs self:filesystem {  associate };

Types adbd_socket and wifip2p_service differ, starting with:
    allow adbd_socket rootfs:filesystem {  associate };
    allow system_server wifip2p_service:service_manager {  add find };
...
...
Types mtd_device and log_device differ, starting with:
    allow mtd_device tmpfs:filesystem {  associate };

Types goldfish_setup_exec and log_device differ, starting with:
    allow goldfish_setup_exec rootfs:filesystem {  associate };

Duplicate Allow Rules

sepolicy-analyze out/target/product/<board>/root/sepolicy dups

Displays duplicate allow rules, i.e. pairs of allow rules that grant the same permissions where one allow rule is written directly in terms of individual types and the other is written in terms of attributes associated with those same types. The rule with individual types is a candidate for removal. The rule with individual types may be directly represented in the source policy or may be a result of expansion of a type negation (e.g. domain -foo -bar is expanded to individual allow rules by the policy compiler). Domains with unconfineddomain (this was removed in 5.1) will typically have such duplicate rules as a natural side effect and can be ignored.

Example output:

sepolicy-analyze out/target/product/generic/root/sepolicy dups

Duplicate allow rule found:
    allow system_server sdcardd:lnk_file {  ioctl read getattr lock open };
    allow system_server domain:lnk_file {  ioctl read getattr lock open };

Duplicate allow rule found:
    allow system_server inputflinger:binder {  transfer };
    allow system_server binderservicedomain:binder {  call transfer };
...
...
Duplicate allow rule found:
    allow su keystore:binder {  call transfer };
    allow appdomain binderservicedomain:binder {  call transfer };

Duplicate allow rule found:
    allow untrusted_app keystore:fd {  use };
    allow appdomain binderservicedomain:fd {  use };

Permissive Domains

sepolicy-analyze out/target/product/<board>/root/sepolicy permissive

Displays domains in the policy that are permissive, i.e. avc denials are logged but not enforced for these domains. While permissive domains can be helpful during development, they should not be present in a final -user build.

Example output on an ENG policy:

sepolicy-analyze out/target/product/generic/root/sepolicy permissive

su

Booleans

sepolicy-analyze out/target/product/<board>/root/sepolicy booleans

Displays the boolean names in the policy (if any). Policy booleans are forbidden in Android policy, so if there is any output, the policy will fail CTS.


Attribute

sepolicy-analyze out/target/product/<board>/root/sepolicy attribute <name>

Displays the types associated with the specified attribute name.

Example output:

sepolicy-analyze out/target/product/generic/root/sepolicy attribute mlstrustedsubject

system_server
netd
zygote
debuggerd
kernel
drmserver
keystore
adbd
dumpstate
runas
uncrypt
installd
init
radio
mediaserver
logd
su
mdnsd
surfaceflinger
racoon
vold
shell
lmkd
servicemanager

Neverallow Checking

sepolicy-analyze out/target/product/<board>/root/sepolicy neverallow [-w] [-d] [-f neverallows.conf] | [-n "neverallow string"]

Check whether the sepolicy file violates any of the neverallow rules from the neverallows.conf file or a given string, which contain neverallow statements in the same format as the SELinux policy.conf file, i.e. after m4 macro expansion of the rules from a .te file. You can use an entire policy.conf file as the neverallows.conf file and sepolicy-analyze will ignore everything except for the neverallows within it. You can also specify this as a command-line string argument, which could be useful for quickly checking an individual expanded rule or group of rules. If there are no violations, sepolicy-analyze will exit successfully with no output. Otherwise, sepolicy-analyze will report all violations and exit with a non-zero exit status.

The -w or --warn option may be used to warn on any types, attributes, classes, or permissions from a neverallow rule that could not be resolved within the sepolicy file. This can be normal due to differences between the policy from which the neverallow rules were taken and the policy being checked. Such values are ignored for the purposes of neverallow checking.

The -d or --debug option may be used to cause sepolicy-analyze to emit the neverallow rules as it parses them. This is principally a debugging facility for the parser but could also be used to extract neverallow rules from a full policy.conf file and output them in a more easily parsed format.

These neverallow rules are also used by the Andriod CTS to check for policy conformance, see cts/tools/selinux/SELinuxNeverallowTestGen.py that generates Java methods.

Example output using the -d option:

sepolicy-analyze out/target/product/generic/root/sepolicy neverallow -d -f out/target/product/generic/obj/ETC/sepolicy_intermediates/policy.conf

neverallow domain kernel : process { transition dyntransition };
neverallow kernel { file_type fs_type - rootfs } : file { entrypoint execute_no_trans };
neverallow { domain - init } fsck : process transition;
...
neverallow system_server { bluetooth_data_file nfc_data_file shell_data_file app_data_file } : file open;
neverallow system_server dex2oat_exec : file { execute execute_no_trans };
neverallow system_server { dev_type - frp_block_device } : blk_file { append create link unlink relabelfrom rename setattr write open read ioctl lock };

setool

The setool utility is not used during the build process and is intended only to produce entries for the mac_permissions.xml file and verify a correctly formated file. It is not supplied in AOSP.

Usage:

Usage: setool [flags] <--build keys|package OR --policy policyFile> <apk> [ <apk> ]*

Tool to help build and verify MMAC install policies.

    --build       Generate an MMAC style policy stanza with a given --seinfo string.
                  The resulting stanza can then be used as an entry in the mac_permissions.xml file.

        package   Policy entry that contains the package name inside the signature stanza.

        keys      Print just a signer tag which contains the hex encoded X.509 certs of the app.

    --policy      Determine if the apks pass the supplied policy by printing the seinfo tag
                  that would be assigned or null otherwise.

       apk        An apk to analyze. All supplied apks must be absolute paths or relative to
                  --apkdir (which defaults to the current directory).

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 output to the given file (defaults to stdout).
  --seinfo Create an seinfo tag for all generated policy stanzas. This is a required flag if using the --build option.

The following examples show the generation and verification process:

setool --build package --seinfo service_app --outfile sepolicy/mac_permissions.xml RunIsolatedService.apk

The output will be:

<signer signature="- certificate will be here -">
    <package name="com.example.runisolatedservice">
        <seinfo value="service_app" />
    </package>
</signer>

Note that for verification via setool requires the segment to be included within a correctly formatted mac_permissions.xml file (i.e. have the <policy> </policy> tags present:

setool --policy sepolicy/mac_permissions.xml RunIsolatedService.apk
/pre>

The output will then be:
<pre>
seinfo tag service_app assigned to ./RunIsolatedService.apk

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 utility:

cc -std=gnu99 uid_to_username.c -o uid_to_username -include $ANDROID_BUILD_TOP/system/core/include/private/android_filesystem_config.h
#include <stdio.h>
#include <stdlib.h>

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 >= AID_ISOLATED_START) {
        printf("username: u%u_i%u\n", userid, appid - AID_ISOLATED_START);
    } else if (userid == 0 && appid >= AID_SHARED_GID_START) {
        printf("username: 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("username: u%u_%s\n", userid, android_ids[n].name);
                printf("Note that only \"%s\" will be shown in 'ps' etc.\n", android_ids[n].name);
                exit(0);
            }
        }
        printf("Failed - invalid uid\n");
    } else {
        printf("username: u%u_a%u\n", userid, appid - AID_APP);
    }
    exit(0);
}


Previous
Home
Next