SELinux Android: Understanding SEAndroid for better device security

SELinux Android

Android is the most popular operating system for custom devices. One reason is the Android Open-Source Project (AOSP) prioritization of security, with solid implementations of multiple powerful security features already in the AOSP ROM.

There is an increased demand for secure Android devices across all industries. Products built on Custom Android ROMs need a robust foundation to achieve maximum security, especially when operating in business-critical processes. One feature used to enhance security is SELinux. SELinux stands for security-enhanced (SE) Linux and is the de facto standard for improving security.

At emteria, SELinux Android is a security cornerstone for the customized operating systems that we adapt for our customers. SELinux can significantly affect overall device security and complement other Android security features such as Android Verified Boot (AVB).

What is SELinux, and why is it used?

SELinux is a security concept embedded in the Linux kernel. It enables system administrators to restrict access to programs and services, files, and network resources through mandatory access control (MAC) policies. Developers and administrators can use MACs in permissive or enforced mode.

Why SELinux is important for Android?

SELinux originated from a joint effort between Red Hat (a major Linux distributor) and the National Security Agency (NSA). Since its public release in December 2000, the SELinux project has maintained it as a part of the Linux Security Module (LSM).

With the release of Android 4.3 and advancements in a derivative of SELinux, it became an integral part of the Android OS, often referred to as SELinux Android or SEAndroid. As such, it supports application isolation and enhances the platform's overall security by reducing the attack surface through MACs.

How to check SELinux status in Android?

There are three options to check the status of SELinux on Android:

  1.  TERMINAL: The ‘getenforce’ command will show the current SELinux mode.
  2.  PROPERTIES: Search for the 'ro.boot.selinux' system property.
  3.  FILE: The file ‘/sys/fs/selinux/enforce’ contains the status.

Understanding SELinux modes in security enhanced Linux

SELinux is implemented into Android like the zero-trust principle, meaning permissions must be actively granted. When checking the SELinux Android status, you will see one of three options: it can be entirely disabled, in SELinux permissive mode, or enforced mode.

These two modes are fundamentally different and have an immediate impact on device security:

  • PERMISSIVE: Although the access is not explicitly granted, the violation is not actively enforced. This event will appear in the logs.
  • ENFORCED: In this mode, violations are enforced and will be logged. Enforced is the default mode on Android.

SELinux permissive mode vs. SELinux enforcing mode

At first glance, the permissive mode appears useless since it only logs violations rather than preventing them. So why use it at all? Why use an intermediate option between on and off?

The permissive mode is essential for testing and debugging purposes. In contrast to enforced mode, the system can run as-is, and the developer can actively look for violations and turn them into specific policies. The kernel logs in ‘dmesg’ and ‘logcat’.

Catching numerous violations in permissive mode is a more effective and integral approach. The enforced mode would disrupt the system and limit testing and development to predefined test cases only. Using the SELinux permissive mode in development and test environments greatly benefits production systems since it ensures that legitimate operations are allowed and don’t disrupt the system.

SELinux Mandatory vs. Discretionary Access Control

Similarly, you might have heard of the discretionary access control (DAC). Why is there yet another concept necessary? The concept of mandatory access control is essential and one of the reasons why SEAndorid is so powerful.

In DAC systems traditionally used in Linux, files and processes have owners. This concept of ownership over resources creates various privilege elevations and thus implies the need for an independent access control system.

MAC systems like SELinux rely on a central authority instead of the concept of ownership. This shift is mandatory to implement a fine-grained access control system independent from users, thus enhancing overall security. SELinux policies define this fine-grained access.

Interaction between DAC and SELinux

In SEAndroid, both concepts are present, while MAC generally has royalty over DAC. This leads to the following:

  1. SELinux operates as an additional layer on top of DAC
  2. Both DAC and SELinux checks must pass for access to be granted
  3. SELinux can restrict access even if DAC would allow it
  4. SELinux ignores DAC permissions in its decision-making process

While this might lead to some confusion at the beginning, you will quickly notice the positive effects on overall device security and flexibility.

A brief introduction to SELinux policies

SELinux policies are the rules that govern and restrict access on the Linux kernel level. Understanding and managing these complexities is essential to ensuring security and system operation.

What is the syntax of SELinux policies?

On a system level, these SELinux Android policies rely on the Type Enforcement (TE) component. TE introduces a scheme to define policy rules, which results in the following sequence:

‘action source target:class:permissions;’

Let’s look at this structure in more detail:

Action: This is the policy's action operator. Since the SELinux implementation is usually tied down, allow is the most common operator. However, some more operators, such as 'dontaudit', 'auditallow', and 'neverallow', are for granular and specific use. Have a look at the AVCRules by the SELinux project for more details.

Source: Policies are mapping between two objects. If an application needs rw access to a file, the application would be the source.

Target: Following this example, the specific file will be the target.

Class: The class specifies the targets’ type. Here, it’s a file.

Permission: These are the individual privileges that are assigned to the source.

Since these policies provide a granular definition of privileges, custom macros (or permission sets) bundle multiple privileges and simplify this often tedious and error-prone process. Think of read and write (rw) permissions as an example.

We recommend the SELinux concept for more context on how to modify SELinux policies in Android.

Visit SELinux concept
SELinux_logo

Where are SELinux policies location?

The policy file location is located in 'system/sepolicy/' for the platforms and 'vendor/sepolicy/' for vendor policies. It is possible and recommended to update existing policy files rather than create numerous new policy files in these directories. However, custom policies should reside in a separate directory.

Policy files have the ‘.te’ extension. You might wonder what the context files are for. Let’s have a look at that in the following.

What is a security context (aka label)?

Each process and object gets a security context assigned in SELinux Android. A security context is necessary to log security-related information, enabling debugging and auditing policies. Like the policy itself, it has a specific scheme:

‘user:role:type:sensitivity:categories’

In security enhanced Android, you can ignore the user, role, and sensitivity since these attributes are not in use. The remaining attributes are of interest, though:

Type: This is the first attribute that matters in SEAndroid and is often the most important for access decisions. It represents the file_type of the policy.

Categories: Categories separate and isolate access on an application level.

Custom categories can be defined, allowing for creating separate security domains. Context files contain these definitions.

SELinux Android implementation

So, how do we implement SELinux Android on our devices? Let’s start from the very beginning. This step-by-step guide will introduce you to the essential steps for implementing SELinux and provide some context.

Kernel and boot configuration

To ensure that your device has the necessary configuration for SELinux Android, ensure that these kernel and boot parameters are set. In this step, we enable SELinux Android in permissive mode, since it simplifies the implementation process without the risk of disrupting any running services.

  1. Enable SELinux Android
    ‘CONFIG_SECURITY_SELINUX=y’
  2. Change kernel_cmdline and switch to permissive mode
    ‘BOARD_BOOTCONFIG := androidboot.selinux=permissive’

Violation analysis

After enabling SELinux Android in permissive mode, it is time to analyze and identify any violations. To do that, we will first reboot the device to ensure that we include everything in the logs.

  1. Reboot the system
  2. Examine the logs for violations during reboot
    ‘adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy’

Look at this chained command closely: We pass the denials to audit2allow. Audit2allow is a powerful tool that generates allow rules from log inputs, saving time and headaches during development.

  1. Identify files and devices that are missing labels. Reuse the labels from the context files where applicable.
  2. Identify processes that need a separate security domain. Security domains should isolate app data between applications and users, respectively.
  3. Identify domains without a domain type. They are listed in ‘init.device.rc’

Policy configuration and development

With these findings and the initial setup at hand, we can now configure SELinux Android:

  1. Set up ‘BOARD_CONFIG.mk’ with ‘BOARD_SEPOLICY_*’ variables.
  2. Review the ‘init.device.rc’ file once more:
    1. Ensure proper assignment of ’mount’ to a labeled filesystem.
    2. Repeat for ‘fstab.device’
  3. Implement and develop custom policies in the *.te files of the appropriate sepolicy directory

With this step-by-step approach, you can enable SELinux Android on your device and add custom policies. After developing, don’t forget to switch to enforced mode. To do this, delete the line of Step 2—now it’s time to test your policies.

How to turn off SELinux Android?

You might want to switch off SEAndroid under some circumstances. The easiest way to turn SEAndroid off is by switching the default mode from enforced to permissive. However, using 'setenforce 0' temporarily disables SEAndroid. In contrast, adding 'enforcing=0 androidboot.selinux=permissive' to 'BOARD_KERNEL_CMDLINE' permanently disables SELinux and remains effective after rebooting.

Why disabling SELinux

Disabling SELinux is generally not recommended since it is an essential feature for device security. However, there are some specific cases for that:

  1. Troubleshooting
  2. Policy Development
  3. Dev/Test Environments

For these reasons, it might be helpful for you to know how to turn off this feature. Two approaches result in a temporary or permanent disabling of SELinux Android.

Temporary disable

A temporary option uses ‘setenforce 0’ to disable SELinux Android. Note that this will only last until the device reboots.

In your Terminal:

‘adb shell su \

setenforce 0’

This setting will temporarily set SEAndroid to permissive mode until reboot. To resume enforced mode, flip 0 to 1.

Permanent disable

To change SELinux persistently, you need to modify the boot image. This modification requires privileges to unlock the bootloader.

Add the following line to ‘BOARD_KERNEL_CMDLINE’:

‘enforcing=0 androidboot.selinux=permissive’

This operation changes the enforced mode to permissive.

Security enhanced Linux in emteria’s Android OS

At emteria, we use our years of expertise in Android platform development to meet all custom requirements and provide solution builders with in-demand security features. Device security is more important than ever before.

We offer a comprehensive set of security-related services that span beyond security enhanced SEAndroid. These security features can be integrated into the Android images that we customize and support for our customers. As part of our customization services, we can tailor necessary security features to specific needs:

  • Enhanced Security: Our experts leverage SEAndroid as part of an extensive security implementation that exceeds the standard implementations
  • Customization: With our customization tools, we can fine-tune any Android BSP to meet industry requirements and maintain high security standards.
  • Extensive support: Keeping up with vulnerabilities and threats is a challenge, let alone the pressure to close them on time. At emteria, we have you covered with regular security patches, version updates, and long-term OS support!

Enable SEAndroid on your device

SELinux Android is a fundamental building block in device security architecture. The integration of SEAndroid into the operating system significantly enhances overall security. Through MAC, developers can restrict and isolate applications and harden the device against security threats such as tampering.

Developing SELinux Android is an essential step in building a comprehensive Android product. SELinux Policies are powerful; however, defining policies that use the entire spectrum of options requires substantial knowledge and experience. Poorly defined policies can impact device performance and—more importantly—potentially introduce backdoors. 

Potential threats arise every day. Your device needs effective security due to a new attack vector or intentional tampering. At emteria, we have your back in providing a secure Android custom ROM based on your requirements! Book a live demo and talk to our experts today.

Build secure Android products, keep them up-to-date

See why emteria is the chosen Android™ customization & management platform for product builders — build modern Android products with the highest security standards.

Book live demo
m-secure-embedded-systems

Table of contents

emteria Demo
See emteria in action