AOSP Framework & Internals
3 min read

SELinux in Permissive vs Enforcing

Learn about SELinux in Permissive vs Enforcing.

SELinux operates in one of two primary states: Enforcing or Permissive. Understanding how to toggle and utilize these modes is essential for an efficient platform development workflow.

Permissive Mode for Development

In Enforcing mode, the SELinux policy is strictly applied. Any access that is not explicitly allowed is denied, and an AVC denial message is logged. This is the required state for all production Android devices.

In Permissive mode, the SELinux policy is evaluated, and AVC denial messages are logged to the kernel buffer (dmesg), but the access is not actually blocked. The operation is allowed to proceed.

Permissive mode is highly valuable during initial bring-up or feature development. When developing a new HAL or system service, you do not want to be blocked by SELinux denials at every step. By running in permissive mode, you can exercise the full functionality of your code, collect all the AVC denials generated along the path, and then use audit2allow to draft the necessary policy once the feature is working.

setenforce Command

You can dynamically switch the SELinux mode on a running device using the setenforce command via adb shell, provided the device is a debuggable build (userdebug or eng).

# Check current status
adb shell getenforce

# Switch to permissive mode
adb shell setenforce 0

# Switch to enforcing mode
adb shell setenforce 1

Note that switching to permissive mode requires root privileges. Production builds (user builds) have SELinux locked into enforcing mode, and setenforce will not work.

Per-Domain Permissive

Sometimes, putting the entire system into permissive mode generates too much noise, hiding the specific denials you care about. AOSP allows you to set specific domains to permissive mode while leaving the rest of the system enforcing.

This is done by using the permissive macro in your .te file:

# Allow my_new_hal_default to run in permissive mode
permissive my_new_hal_default;

This is the recommended approach for developing new components, as it isolates the security relaxation to the specific process you are working on, ensuring you do not mask issues in other parts of the system.

Enforcing Mode Requirement for CTS

The Android Compatibility Definition Document (CDD) mandates that all certified devices must ship with SELinux in Enforcing mode. There are no exceptions for production devices.

Furthermore, the Compatibility Test Suite (CTS) includes tests that explicitly verify the device is in Enforcing mode. If a device manufacturer forgets to switch from permissive to enforcing before finalizing their build, the device will fail CTS certification. Therefore, all policy development must eventually be finalized, permissive declarations removed, and the system tested under strict Enforcing mode before release.