In the world of Android modding, people tend to regard root access as the cornerstone of all things. It allows users to take complete control of their devices and add features that aren’t always available in the stock configuration. But as they say — “with great power comes great responsibility” — it’s not wise to bypass Android’s security model unless you know what you’re getting into. For veteran Android enthusiasts on our forums, you are probably aware of the potential for backdoors to exist on your device, and you are more likely to be running a trusted root-enabled mod on top of the latest Android version with the latest security patches. Having said that, you might know a few people who don’t really care about what root tweaks they install so long as they seemingly work for them. This is why you can still find a truckload of mods that only work when SELinux is set to permissive, which, in turn, leave their users extremely susceptible to security threats.
What is SELinux
SELinux, or Security-Enhanced Linux, is a Linux kernel security module specifically designed for access and management of security policies. Originally introduced in Android 4.3 Jelly Bean and set to its Enforcing mode as default since Android 4.4 KitKat, SELinux helps enforce access control rights and attempts to prevent privilege escalation attacks. In a nutshell, SELinux acts as a hurdle for unauthorized control over your device, such as an app or vulnerability aiming to gain root access maliciously. Setting SELinux to “Enforcing” by default is one of the key ways that normal users are protected from such attacks.
Why Permissive SELinux is not recommended
To reiterate, the typical way to achieve root access on an Android device doesn’t necessarily need to change the SELinux status. Shifting SELinux mode from “Enforcing” to “Permissive” is intentionally disabling one of the key security features on the device, which is why the user has to explicitly allow it to happen by installing a specialized custom kernel or modifying the parameters of the existing boot image. A poorly coded mod lacking a proper SELinux policy usually forces end-users to shift to permissive SELinux and essentially expands the attack surface. That’s exactly what developer vvb2060 demonstrated when they published a proof of concept privilege escalation method where the only requirement to gain control is permissive SELinux.
For a user to get full root access on their own device running Android 10 (or higher) with SELinux set to permissive is shockingly easy to do: All you have to do is press install, and “Magica” will automatically gain root access in a service and install Magisk to the boot image. This is something far wider in scope than just tweaking your device. According to XDA Senior Recognized Developer and Magisk maintainer topjohnwu, any arbitrary app, including malware, can permanently root your device without your consent and permission by utilizing the PoC.
Imagine this scenario: you are using a custom kernel that ships with SELinux permissive. You accidentally install a malware using this loophole. The malware installs a modified “malicious Magisk” to permanently gain full root access. BOOM, your device is now #pwned.
— John Wu (@topjohnwu) February 9, 2021
If you’re wondering on a technical level what Magica is exploiting, topjohnwu explained the following in a Reddit post:
“When SELinux is permissive during boot, zygote will know this and disable seccomp syscall filters. This basically unrestricts what system calls are allowed in 3rd party processes.
On Android 10+, there is a new “undocumented” feature called “App Zygote” where 3rd party apps are allowed to spawn its own Zygote for “Isolated Services” (also nearly undocumented). Both “App Zygote” and “Isolated Services” are special features designed for Chrome/Webview*. App Zygote processes run with special permissions, and with seccomp disabled, it can call setuid 0 and escalate its privilege and gain root access.
It is still somehow restrictive compared to what normal root solutions provide (e.g. Magisk), however tons of security measures in Android will be completely defeated when UID=0. For example, it is enough to be used to patch boot images, which means it can be used to inject malware such as modified Magisk to help it gain “real” root permissions.
Update: what can UID=0 itself do? Within Android’s framework, almost all services have a blind green light when the requesting process’s UID is 0. This means this root process is capable of manipulating tons of stuff using Android specific APIs (e.g. ActivityManager)”
*According to developer aviraxp, these two features are more generally designed “for sharing resources and memory between multiple isolated processes.”
The general lack of consciousness
Even though ignoring SELinux guidelines is very serious, some Android OEMs are deliberately giving it the go-by. ASUS, for example, recently rolled out a software update to address the Widevine DRM level downgrade issue on the ZenFone 7 and the ROG Phone 3. Developers have discovered that the recent firmwares purposefully set SELinux as permissive for a brief period of time on each boot. As a consequence, it is theoretically possible to gain root access on these devices without even unlocking the bootloader, though this has yet to be demonstrated.
— Luca Stefani (@luca020400) February 9, 2021
Considering the irreparable harm that can be inflicted on users targeted by malware on a permissive SELinux environment, we strongly suggest everyone keep it on enforcing unless absolutely necessary. While we are just lucky to have a proof of concept exploit, we have no idea how many malware authors already know about this path of attack. After all, a victim will continue to remain oblivious to the compromised state of their device if they did not witness the exploit being actively used, which is not difficult to achieve for a rogue app that has persistent root access.