When bringing up a new hardware board or developing custom HAL (Hardware Abstraction Layer) drivers in Android AOSP, strict SELinux Enforcing mode will block unauthorized HAL system calls, resulting in silent boot loops or permission denied crashes. Temporarily switching SELinux to Permissive mode allows kernel operations to succeed while logging access violations (avc: denied) to Logcat.

Method 1: Permanent AOSP Build Config (BoardConfig.mk)

To compile an AOSP engineering build that boots into SELinux Permissive mode by default, append androidboot.selinux=permissive to the kernel command line in your device target’s BoardConfig.mk:

device/<vendor>/<target>/BoardConfig.mkmake
# Append SELinux Permissive command line parameter to kernel boot arguments
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive

Method 2: Runtime ADB Command (userdebug / eng builds)

On running userdebug or eng AOSP builds, toggle SELinux mode dynamically via ADB without rebuilding the kernel:

ADB Terminal Commandsbash
# 1. Check current SELinux status (Enforcing or Permissive)
adb shell getenforce
 
# 2. Switch SELinux to Permissive mode (Requires root!)
adb root
adb shell setenforce 0
 
# 3. Verify Permissive state active
adb shell getenforce
# Output: Permissive

Converting Logcat Denials into SELinux Policies (audit2allow)

Permissive mode is intended only for development. Use audit2allow to generate permanent .te SELinux policy rules before shipping production firmware:

Generating SELinux Policy Rulesbash
# Filter AVC denial logs from logcat and generate policy rules
adb shell dmesg | grep "avc: denied" | audit2allow -p out/target/product/<target>/root/sepolicy
 
# Generated Policy Rule Example (my_hal.te):
# allow my_hal_service vendor_device:chr_file { read write open };