How to customize Android security using SEAndroid

This article teaches you how to use SEAndroid to customize Android security on Android 4.4 (Kitkat)

Published Date
06 - Oct - 2014
| Last Updated
28 - Oct - 2014
How to customize Android security using SEAndroid

Security Enhancements for Android (SEAndroid)

Android has added some new features to the 4.4 version of the Android OS ("Kitkat"). The most important change among the new features is the ability to integrate SEAndroid in enforcing mode, which means access permissions for all Android components is under the control of SEAndroid.

What is SEAndroid? SEAndroid refers to Security Enhancements for Android, a security solution for Android that identifies and addresses critical gaps. Initially, the project's scope was to enable the use of SELinux in Android to limit the damage that can be done by flawed or malicious apps and to enforce separation guarantees between apps. However, the scope of the project changed to include more than SELinux. SEAndroid is now the overall framework for implementing SELinux mandatory access control (MAC) and middleware mandatory access control (MMAC) on Android.

Let's clarify some concepts related with SEAndroid:

  • Security-Enhanced Linux* (SELinux) is an implementation of mandatory access control using Linux Security Modules (LSM) in the Linux kernel, based on the principle of least privilege. It is not a Linux distribution but instead a set of modifications that can be applied to UNIX*-like operating systems, such as Linux and BSD.
  • Discretionary Access Control (DAC) is the standard security model for Linux. In this model, access privileges are based on the user identity and object ownership.
  • Mandatory Access Control (MAC) limits privileges for subjects (processes) and objects (file, socket, device, etc.).

SELinux does not change any existing security in the Linux environment; instead, SELinux extends the security model to include Mandatory Access Control (e.g., both MAC and DAC are enforced in the SELinux environment).

SEAndroid enhances the Android system by adding SELinux support to the kernel and user space to:

  • Confine privileged daemons to protect them from misuse and limit the damage that can be done via privileged daemons
  • Sandbox and isolate apps from each other and from the system
  • Prevent privilege escalation by apps
  • Allow application privileges to be controlled at installation and runtime using MMAC
  • Provide a centralized, analyzable policy

Furthermore, in Android 4.4, SEAndroid is enabled in the Enforcing mode, instead of the non-functional disabled mode or the notification-only permissive mode, which means that any invalid operation will be prohibited in the Android run-time environment.

The SEAndroid Policy

SEAndroid policy is one of the cores of the entire SEAndroid security mechanism. In addition, the security architecture must also have a strict security policy to ensure that the access subject has only minimal access permissions to the object, so that the program can execute the basic functions but will be prevented from executing malicious operations.

As mentioned above, SEAndroid's implementation is in enforcing mode, instead of the non-functional disabled mode or the notification-only permissive mode, to act as a reference and facilitate testing and development.

The security context of SEAndroid is basically consistent with SELinux. The four parts, user, role, type, sensitivity, i.e., u: object_r: system_data_file: s0 are described below:

  • User: The security context of the first column is the user in SEAndroid and the only one that is u.
  • Role: The second column indicates the role in the SEAndroid, r and object_r, respectively.
  • Type: For the third column type, SEAndroid defines the 139 different policy types, such as device type, process type, file system type, network type, IPC type, and so on.
  • Security level: The fourth column is designed for Multiple Level Security (extension MLS), which is the access mechanism to add security context and format sensitivity [: category list] [- sensitivity [: category list]], for example s0 - s15: c0 - c1023, whereas the category may not be required in the current Android version. The combination of sensitivity and category together declares the current security level, and numbers are identified around the lowest and highest level of security. The parameters of this column are used in the MLS constraint checking, with "15" and "1023" representing the maximum sensitivity and category. This parameter range can be defined in the

The security context is the most important part of the third column type, and the process type is called domain. Type is the most important of SEAndroid parameters and the policy parameters are greatly expanded, so the system for each file marked with the appropriate type becomes extremely important.

The SEAndroid policy sources are located under external/sepolicy.

The policy consists of source files used to generate the SELinux kernel policy file, a file_contexts configuration, a property_contexts configuration, a seapp_contexts configuration, and a mac_permissions.xml configuration.

  • The file_contexts configuration is used to label files at build time (e.g., the system partition) and at run time (e.g., device nodes, service socket files, /data directories created by init.rc, etc.).
  • The property_contexts configuration is used to specify the security context of Android properties for permission checking purposes.
  • The seapp_contexts configuration is used to label app processes and app package directories.
  • The mac_permissions.xml configuration is the middleware MAC policy.

The device-specific policy sources are located under device/<vendor>/<device>.

  • The device-specific policy can be specified by defining BOARD_SEPOLICY_DIRS, BOARD_SEPOLICY_UNION and/or BOARD_SEPOLICY_REPLACE variables in a file under the device/<vendor>/<device> or vendor/<vendor>/<device> directories, i.e., the configuration file for Intel® Atom™ processor-based tablet (codenamed Bay Trail) FFRD8 is "/device/intel/baytrail/".
  • An example can be found in device/intel/baytrail/, which defines these variables to reference device-specific policy files under device/intel/baytrail/sepolicy.
  • Documentation for per-device policies can be found in the external/sepolicy/README.

Change the SEAndroid Policy

SEAndroid policy files exist under /external/sepolicy. You can change these policy files to see what happens if the new policy is applied. Please pay close attention when changing the policy files, for the incorrect configuration may cause the whole system to halt during booting. Following is an example:

Step 1: Check before modification

First, we need to check the file "/device/intel/baytrail/". The sepolicy configuration of this board is as follows:


BOARD_SEPOLICY_DIRS defines the directory where the device-specific policy files exist. BOARD_SEPOLICY_UNION means the final policy configuration is the result of combining the general policy files and the device-specific policy files. During the Android building procedure, the build system will check the conflict between the different policies. If BOARD_SEPOLICY_ REPLACE is applied, it means the device-specific policies will replace the configuration of general policies.

Second, we need to open the file "/external/sepolicy/untrusted_app.te" and check that the following lines are there:

01Allow untrusted_app shell_data_file:file rw_file_perms
03Allow untrusted_app shell_data_file:dir r_dir_perms

The two policy items above offer the untrusted apps (the normal apps, not the system apps) the permissions of reading/writing the files and reading the directories with the type of shell_data_file under the runtime environment. The shell_data_file points to any file in /data/local/tmp/ under the run-time environment, which is defined in /external/sepolicy/file_contexts under the development environment as follows:

/data/local/tmp(/.*)? u:object_r:shell_data_file:s0

But these permissions listed above have some limitations.  If the files and directories exist in /data/loacal/tmp/, the untrusted apps can read/write these files and enter these directories. But the untrusted apps cannot create their own files and directories under /data/local/tmp/. Only system apps or services can create files or directories for the untrusted app. If we want to give more permission to the untrusted apps, we can make the changes described in Step 2.

Step 2: Add the new policy items

Now we edit the file "/device/intel/baytrail/sepolicy/untrusted_app.te" and add the following two lines to the end of the file:

01Allow untrusted_app shell_data_file:file create_file_perms
03Allow untrusted_app shell_data_file:dir create_dir_perms

These two items give permission to the untrusted apps to create the files and directories in /data/local/tmp/ in the run-time environment, which is defined in /external/sepolicy/file_contexts under the following development environment:

/data/local/tmp(/.*)? u:object_r:shell_data_file:s0

The basic file/directory permissions are defined in /external/sepolicy/global_macros:

01define('x_file_perms', '{ getattr execute execute_no_trans }')
03define('r_file_perms', '{ getattr open read ioctl lock }')
05define('w_file_perms', '{ open append write }')
07define('rx_file_perms', '{ r_file_perms x_file_perms }')
09define('ra_file_perms', '{ r_file_perms append }')
11define('rw_file_perms', '{ r_file_perms w_file_perms }')
13define('rwx_file_perms', '{ rw_file_perms x_file_perms }')
15define('link_file_perms', '{ getattr link unlink rename }')
17define('create_file_perms', '{ create setattr rw_file_perms link_file_perms }')
19define('r_dir_perms', '{ open getattr read search ioctl }')
21define('w_dir_perms', '{ open search write add_name remove_name }')
23define('ra_dir_perms', '{ r_dir_perms add_name write }')
25define('rw_dir_perms', '{ r_dir_perms w_dir_perms }')
27define('create_dir_perms', '{ create reparent rmdir setattr rw_dir_perms link_file_perms }')

We can see the permissions, such as the file operation "{ getattr open read ioctl lock }", are the same as the file operation functions in the real file system.

Finally, we need to rebuild the Android source tree and flash a new image into the Bay Trail FFRD8 device.

Verify the SEAndroid Policy

After the FFRD8 is booted, we can download a FileManager app from an Android App Store, then open the command shell from the FileManager menu. This allows us to emulate the condition of untrusted apps executing file operations.

A new file and new directory can be created by entering the directory /data/local/tmp/ and creating a new file and a new directory. (With a standard FFRD8 device, creating new file and new directory is prohibited.) The result of a different policy is shown in the comparison image below, with the chart on the left showing the result of unchanged polices, and the chart on the right showing the result of changed policies:

Figure 1: File permissions comparison between standard policies and changed policies


This article introduces the basic concept of SEAndroid policy and presents an example how to add a new policy to the SEAndroid policy set based on an Intel Atom processor-based platform (codenamed Bay Trail). It will help the ODMs interested in custom-built SEAndroid to have a preliminary understanding of the SEAndroid policy mechanism.

About the Author

Liang Z. Zhang is an application engineer in Intel PRC Developer Relationship Division, responsible for supporting enterprise app developers to enable security technologies based on Intel® platforms.

For more such Android resources and tools from Intel, please visit the Intel® Developer Zone