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.
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:
- TERMINAL: The ‘getenforce’ command will show the current SELinux mode.
- PROPERTIES: Search for the 'ro.boot.selinux' system property.
- FILE: The file ‘/sys/fs/selinux/enforce’ contains the status.
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:
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.
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.
In SEAndroid, both concepts are present, while MAC generally has royalty over DAC. This leads to the following:
While this might lead to some confusion at the beginning, you will quickly notice the positive effects on overall device security and flexibility.
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.
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.
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.
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.
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.
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.
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.
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.
With these findings and the initial setup at hand, we can now configure SELinux Android:
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.
Disabling SELinux is generally not recommended since it is an essential feature for device security. However, there are some specific cases for that:
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.
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.
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.
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:
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.