Difference between revisions of "NB SEforAndroid 2"

From SELinux Wiki
Jump to: navigation, search
(buildeopbundle)
(buildifwbundle)
Line 977: Line 977:
  
 
=== buildifwbundle ===
 
=== buildifwbundle ===
The <tt>buildifwbundle</tt> tool will produce an Android "bundle" for updating the Intent Firewall 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.
+
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.
 
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.
Line 1,034: Line 1,034:
 
1
 
1
 
</pre>
 
</pre>
 
  
 
== post_process_mac_perms ==
 
== post_process_mac_perms ==

Revision as of 11:29, 31 July 2014

Policy File Configuration Details

This section details the specific SE for Android policy configuration files (i.e. those not used by 'standard' Linux based SELinux). Where those files are used to compute contexts using the SE for Android libselinux functions, those functions are also described with examples.

SELinux MAC Configuration Files

seapp_contexts File

This file is loaded and sorted into memory automatically on first use of one of the following SE for Android libselinux functions that are called by the SE for Android enabled services:

selinux_android_setcontext - Computes process security contexts.
selinux_android_setfilecon - Computes file/directory security contexts.
selinux_android_seapp_context_reload will reload this file.

The build process supports additional seapp_contexts files to allow 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 SEAndroid 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
user=_app seinfo=platform domain=platform_app type=app_data_file
user=_app domain=untrusted_app type=app_data_file


Entry Definitions

The following has been extracted from the default file with some additional comments that describe the parameters and how they are used to compute a context:

Input selectors from seapp_contexts file:

isSystemServer (boolean)
user (string)
seinfo (string)
name (string) - A package name e.g. com.example.demo
path (string) - A path name (added to ensure correct labeling of some files).
sebool (string) - The boolean must be ‘active’ (enabled/true)

Notes:

isSystemServer=true can only be used once.
An unspecified isSystemServer defaults to false.
An unspecified string selector will match any value.
A user string selector that ends in * will perform a prefix match.
user=_app will match any regular app UID.
user=_isolated will match any isolated service UID.
All specified input selectors in an entry must match (i.e. logical AND).
Matching is case-insensitive.

Precedence rules:

1) isSystemServer=true before isSystemServer=false.
2) Specified user= string before unspecified user= string.
3) Fixed user= string before user= prefix (i.e. ending in *).
4) Longer user= prefix before shorter user= prefix.
5) Specified seinfo= string before unspecified seinfo= string.
6) Specified name= string before unspecified name= string.
7) Specified path= string before unspecified path= string.
8) Specified sebool= string before unspecified sebool= string.

Outputs:

domain (string) - The type component of a process context.
type (string) - The type component of a file/directory context.
levelFrom (string; one of none, all, app, or user) - A level that will be automatically computed based on the parameter.
level (string) - A predefined level (e.g. s0:c1022.c1023)

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 Process Context

To compute an app process context the selinux_android_setcontext function is called that will use the parameters passed, plus the contents of the seapp_contexts file. The function parameters are:

#include <selinux/android.h>

int selinux_android_setcontext(uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname);

The context is then computed using the information as follows:

The uid is converted to a string that is then used to match the user= entries in the seapp_contexts file as follows:
If an Android system service the uid is converted to a string via an internal Android table (e.g. "radio", "system").
If an isolated service (determined from the apps AndroidManifest.xml file) the _isolated string is used .
For any other app or service the _app is used.
The isSystemServer value must match that set in the running system and be true or false. It will be matched against the isSystemServer= entries in the seapp_contexts file.
seinfo may be NULL or that obtained from the mac_permissions.xml file. It will be matched against the seinfo= entries in the seapp_contexts file.
pkgname may be NULL or that obtained from the Android package. It will be matched against the name= entries in the seapp_contexts file.
The remaining seapp_contexts entries will be used as follows:
The sebool= parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
The levelFrom= and level= parameters if present will be used to determine the level component of the security context.
The domain= is used to set the process context and must match a context in the policy. Determines the type component of the security context.

If a context is computed, it is validated against policy and if correct setcon(3) will then set the 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 input selectors:
    isSystemServer true
    seinfo         null
    name           null
    path           null
    sebool         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 input selectors:
    isSystemServer false
    seinfo         platform
    name           com.android.phone
    path           null
    sebool         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 1587 63   com.android.phone

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

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

seapp_contexts input selectors:
    uid            10013
    isSystemServer false
    seinfo         default
    name           com.android.seandroid_admin
    path           null
    sebool         null

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

Outputs:
    domain untrusted_app
    level  s0

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

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

This is a third party app that will run an isolated service that has been installed as a platform app:

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

seapp_contexts input selectors: 
    uid            10058
    isSystemServer false
    seinfo         default
    name           com.example.runisolatedservice
    path           null
    sebool         null

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

Outputs:
    domain untrusted_app
    level  s0

Computed context = u:r:untrusted_app:s0
username computed from uid = u0_a58

Result using ps -Z command:

LABEL                USER   PID  PPID NAME
u:r:untrusted_app:s0 u0_a58 1138 64   com.example.runisolatedservice

The isolated service will then run as follows:

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

seapp_contexts input selectors:
    uid            99000
    isSystemServer false
    seinfo         platform
    name           com.se4android.isolatedservice
    path           null
    sebool         null

Matching seapp_contexts entry:
    user=_isolated domain=isolated_app

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

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

Result using ps -Z command:
LABEL               USER  PID  PPID NAME
u:r:isolated_app:s0 u0_i0 1211 70   com.se4android.isolatedservice


Computing a Directory Context

To compute an app package directory context the selinux_android_setfilecon function is called that will use the parameters passed, plus the contents of the seapp_contexts file. The function parameters are:

#include <selinux/android.h>

int selinux_android_setfilecon(const char *pkgdir, const char *pkgname, const char *seinfo, uid_t uid);

The context is then computed using the information as follows:

pkgdir is the file or directory to be labeled with the computed context.
pkgname may be NULL or that obtained from the Android package. It will be matched against the name= entries in the seapp_contexts file.
seinfo may be NULL or that obtained from the mac_permissions.xml file. It will be matched against the seinfo= entries in the seapp_contexts file.
The uid is converted to a string that is then used to match the user= entries in the seapp_contexts file as follows:
If an Android system service, the uid is converted to a string via an internal Android table (e.g. "radio", "system").
If an isolated service the _isolated string is used.
For any other app or service the _app is used.
The remaining seapp_contexts entries will be used as follows:
The sebool= parameter if present will be matched against the SELinux boolean name list. If present, the boolean must be active.
The levelFrom= and level= parameters if present will be used to determine the level component of the security context.
The type= is used to set the file object context and must match a context in the policy. Determines the type component of the security context.

If a context is computed, it is validated against policy and if correct setfilecon(3) will then be used to label pkgdir with the computed context. The following example is from 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 input selectors: 
    uid            10046
    isSystemServer false
    seinfo         default
    name           com.example.runisolatedservice
    path           null
    sebool         null

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

Outputs:
    type  app_data_file
    level s0

Computed context = u:object_r:app_data_file:s0
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 com.example.runisolatedservice


property_contexts File

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 to allow 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 File

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 to allow 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!


Install-time MMAC Configuration File

The mac_permissions.xml file is used to configure 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 Process 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 to allow 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 SEAndroid mac_permissions.xml file:

  • 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.


EOps MMAC Configuration File

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 harcoded 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 frontend 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 AppOpsManager.java. Just use the string version of each op without the OP_ prefix in your policy tags. These are the current entries (July '14):

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

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></nowiki>

</app-ops>


Intent Firewall MMAC Configuration File

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"></nowiki>
        <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_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_relo domain=shared_relo
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app
user=_app seinfo=platform domain=platform_app type=app_data_file
user=_app domain=untrusted_app type=app_data_file
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 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...]</nowiki>


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 BOARD_SEPOLICY_UNION and BOARD_SEPOLICY_REPLACE variables and is processed via m4 macros.

insertkeys.py allows for mapping any string contained in TARGET_BUILD_VARIANT with a specific path to a pem file. Typically TARGET_BUILD_VARIANT is either user, eng or userdebug. Additionally "ALL" may be specified to map a path to any string specified in TARGET_BUILD_VARIANT. All tags are matched verbatim and all options are matched lowercase. The options are "tolowered" automatically for the user, it is convention to specify tags and options in all uppercase and tags start with @.

An example keys.conf file 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!
sepolicy-check -s su -t security_prop -c property_service -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 that are currently supported include:

Type Equivalence

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

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 -e -P out/target/product/se4a_device/root/sepolicy

Types adbd_socket and mdns_socket are equivalent.
Types rild_debug_socket and init_tmpfs are equivalent.
Types rild_debug_socket and qemud_tmpfs are equivalent.
Types surfaceflinger_service and mediaserver_service are equivalent.
Types surfaceflinger_service and inputflinger_service are equivalent.

Type Difference

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

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 -d -P out/target/product/se4a_device/root/sepolicy

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

Types adbd_socket and hci_attach_exec differ, starting with:
allow system_server adbd_socket:sock_file { ioctl read write getattr lock append open };
allow debuggerd hci_attach_exec:file { ioctl read getattr lock open };

Types adbd_socket and system_server differ, starting with:
allow adbd_socket rootfs:filesystem { associate };
allow system_server rootfs:filesystem { getattr };


Duplicate Allow Rules

sepolicy-analyze -D -P out/target/product/<board>/root/sepolicy

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 will typically have such duplicate rules as a natural side effect and can be ignored.

Example output:

sepolicy-analyze -D -P out/target/product/se4a_device/root/sepolicy

Duplicate allow rule found:
allow init hci_attach_exec:file { read getattr execute open };
allow unconfineddomain exec_type:file { ioctl read getattr lock execute open };

Duplicate allow rule found:
allow ueventd device:dir { write add_name remove_name };
allow ueventd dev_type:dir { ioctl read write create getattr setattr unlink link rename add_name remove_name reparent search rmdir open };


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

The output will then be:

seinfo tag service_app assigned to ./RunIsolatedService.apk


selinux-network.sh Configuration

This file may become obsolete, however to enable and configure it for loading iptables(8) with SECMARK information as part of the policy build, the following will need to be carried out.

Add an entry in the device make file:

PRODUCT_PACKAGES += selinux-network.sh

Replace the default version in external/sepolicy by an entry in the BoardConfig.mk file (assumes there is a BOARD_SEPOLICY_DIRS entry):

BOARD_SEPOLICY_REPLACE += selinux-network.sh

Then either load via adb or add to the init.rc file:

## Daemon process to be run by init.
##
...
# Load iptables configuration.
service netlabels /system/bin/selinux-network.sh
     class core
      oneshot

During the build the file will be installed at /system/bin/selinux-network.sh and may be executed at system initialisation time or via adb.

Example selinux-network.sh entries:

#!/system/bin/sh

############### IPTABLES FOR V4 </nowiki>Using security table #####################
IPTABLES="/system/bin/iptables"

# Common rules that copy connection labels to established and related packets:
$IPTABLES -t security -A INPUT  -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore
$IPTABLES -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

# Create a chain for the NetLabelDemo app:
$IPTABLES -t security -N SELINUX_NET_APPS
# Add rules to mark the demo packets:
$IPTABLES -t security -A SELINUX_NET_APPS -j SECMARK --selctx u:object_r:net_apps_packet:s0
$IPTABLES -t security -A SELINUX_NET_APPS -j CONNSECMARK --save
$IPTABLES -t security -A SELINUX_NET_APPS -j ACCEPT
$IPTABLES -t security -A OUTPUT -p tcp --dport 9999 -j SELINUX_NET_APPS
$IPTABLES -t security -A INPUT  -p tcp --sport 9999 -j SELINUX_NET_APPS

Notes:

  1. Adding entries to this file will also require additional policy rules to be added for the device.
  2. Kernels supplied as part of AOSP or SEAndroid may not have the kernel build parameters to support all the SECMARK features. The following additional kernel parameters will enable these:


a) Enable iptables 'security' table in kernel (although the mangle table may be used instead):

CONFIG_IP_NF_SECURITY=y
CONFIG_IP6_NF_SECURITY=y

b) Enable SECMARK/CONNSECMARK in kernel:

CONFIG_NETWORK_SECMARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y

Appendix D - 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></nowiki>
#include <stdlib.h></nowiki>

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);
}