Security-Enhanced Linux in Android

The Android security model is based in part on the concept of application sandboxes. Each application runs in its own sandbox. Prior to Android 4.3, these sandboxes were defined by the creation of a unique Linux UID for each application at time of installation. Starting with Android 4.3, Security-Enhanced Linux (SELinux) is used to further define the boundaries of the Android application sandbox.

As part of the Android security model, Android uses SELinux to enforce mandatory access control (MAC) over all processes, even processes running with root/superuser privileges (a.k.a. Linux capabilities). SELinux enhances Android security by confining privileged processes and automating security policy creation.

Many companies and organizations have contributed to SELinux; their contributions are publicly available for review on android.googlesource.com, aka the Android Open Source Project (AOSP). With SELinux, Android can better protect and confine system services, control access to application data and system logs, reduce the effects of malicious software, and protect users from potential flaws in code on mobile devices.

Android includes SELinux in enforcing mode and a corresponding security policy that works by default across AOSP. In enforcing mode, illegitimate actions are prevented and all attempted violations are logged by the kernel to dmesg and logcat. Android device manufacturers should gather information about errors so they may refine their software and SELinux policies before enforcing them.

Background

SELinux operates on the ethos of default denial: Anything not explicitly allowed is denied. SELinux can operate in one of two global modes:

  • Permissive mode, in which permission denials are logged but not enforced.
  • Enforcing mode, in which permissions denials are both logged and enforced.

SELinux also supports a per-domain permissive mode in which specific domains (processes) can be made permissive while placing the rest of the system in global enforcing mode. A domain is simply a label identifying a process or set of processes in the security policy, where all processes labeled with the same domain are treated identically by the security policy. Per-domain permissive mode enables incremental application of SELinux to an ever-increasing portion of the system and policy development for new services (while keeping the rest of the system enforcing).

The Android 5.0 release moved to full enforcement of SELinux, building on the permissive release of Android 4.3 and the partial enforcement of Android 4.4. With this change, Android shifted from enforcement on a limited set of crucial domains (installd, netd, vold and zygote) to everything (more than 60 domains). Specifically:

  • Everything is in enforcing mode in Android 5.x and higher.
  • No processes other than init should run in the init domain.
  • Any generic denial (for a block_device, socket_device, default_service, etc.) indicates that device needs a special domain.

As a result, manufacturers need to better understand and scale their SELinux implementations to provide compatible devices.

Additional resources

For help constructing useful SELinux policies, refer to the following resources: