How an Anime Game’s Root Detection led to the discovery of a Security Vulnerability in phones from LG, OnePlus, Huawei, Xiaomi, and others
The mobile Android operating system is used on over 2 billion devices each month by both regular consumers and tech enthusiasts. Although the number of people who unlock the bootloader and root their smartphones is relatively small when compared to the overall population of Android users, there’s still a lot of us out there on forums like XDA and Reddit. Magisk is an indispensable tool for the tinkering community. It provides systemless root access and has tools like MagiskHide to enable rooted users to continue using the apps, games, and services they enjoy without restrictions. However, a popular Anime game has been cleverly abusing a system security vulnerability to bypass Magisk’s anti-root detection. Here’s how that works and which devices are affected by this security vulnerability.
- A game has used a bug to detect if a device has been rooted. If the device is rooted, the game blocks the user from playing.
- The bug allows an app to read the status of other apps in memory, without needing any special permissions. The bug does not allow apps to steal any data from other apps. The bug is not severe and is fairly harmless.
- Google is already aware of the issue and has updated their testing tools to make sure that all devices are protected.
A popular Anime game called Fate/Grand Order blocks rooted users from attempting to play the game. XDA Recognized Developer topjohnwu, the lead developer of Magisk, previously discovered a way to bypass Fate/Grand Order’s root detection, but his solution was not working on his OnePlus 6 despite his best efforts. Determined not to give up, the developer analyzed Fate/Grand Order to figure out how it was still detecting root on his OnePlus device. As he explains in his Medium post, this led him to the discovery of a security vulnerability that Fate/Grand Order was seemingly abusing to continue detecting root access on OnePlus devices.
Procfs and Android
On Unix-based operating systems, there’s a special filesystem called “procfs” containing information on processes (think apps) such as their memory usage (think RAM), status (whether the process is running, sleeping, etc.). On most Unix-based operating systems, the user and apps have easy access to procfs to see what kinds of apps and services are running on their system (think of it like Window’s Task Manager.) However, Google began to lock down access to procfs starting in Android 7.0 Nougat. Before Android Nougat, apps like SystemPanel were able to collect data on what apps were running without needing any special permissions. After Android Nougat, apps need to use APIs like UsageStats or AccessibilityService, both of which are gated by permissions that must be granted by the user.
Google prevents apps from reading the status of other apps via procfs by mounting /proc with the flag “hidepid=2.” By mounting procfs with hidepid=2, apps can only see the status of their own process. Thus, an app would need to use the accepted APIs like UsageStats or AccessibilityService to gain information on what apps and services are running on the device.
What if procfs isn’t mounted with hidepid=2? Well, then apps would freely be able to read the status of other apps (and mount points) running on the system without needing any extra permissions*. Google mounts procfs with hidepid=2 on their own devices, but they don’t enforce this requirement on devices from other manufacturers. Several devices from LG, OnePlus, Huawei/Honor, Xiaomi, and others have not been mounting procfs with hidepid=2, which is what apps like Fate/Grand Order take advantage of to detect whether Magisk is present on the device.
*A security change in Android 9 Pie prevents apps from reading information outside of their own “SELinux context” because every app is now isolated individually. SELinux is a kernel module that acts as a gatekeeper of sorts, blocking apps and services from accessing files they’re not supposed to. A SELinux context is like a label for a file which has information like the user and role. Apps with the same SELinux context can read information about other apps in the same context if the hidepid=2 flag is not enabled for procfs. On devices running Android 9 Pie, only apps that are built targeting Android Pie will have Android Pie’s new SELinux changes apply to them. Apps that target Android 8.1 Oreo or below will use the old SELinux rules, allowing them to access information about processes in the same SELinux context so long as procfs is mounted without hidepid=2. Most apps running on your device should at least be targeting Android 8.0 Oreo thanks to new Google Play requirements, but many won’t have been updated to target Android Pie just yet.
The following screenshots show the consequences of not mounting procfs with hidepid=2.
How bad is this?
If we were to compare this system vulnerability to exploits like Fusée Gelée, Blueborne, KRACK, and Meltdown/Spectre, then this bug pales in comparison. Apps can’t use this to gain root access or steal your passwords. Your banking accounts are safe, and so are your credit cards. The worst an app can do is tell whether another app is running on your device, which has very limited uses. Remember that this is standard behavior on many GNU/Linux distributions and that Google only recently started blocking access to procfs with Android Nougat. This bug allows apps to bypass needing certain permissions to monitor other processes, but they still can’t break Android’s sandbox and steal data from other apps. Regardless, this is unintended behavior and breaks a privacy feature of Android, so it must be fixed.
Is my device affected?
Here is a list of devices that we have found to not mount procfs with hidepid=2:
|OEM||Device||Android Version||procfs Leaks|
|Asus||ZenFone 5Z||Android 8.0 Oreo||Yes|
|BlackBerry||KEY2||Android 8.0 Oreo||No|
|Essential||PH-1||Android 9 Pie||No|
|Pixel 2||Android 9 Pie||No|
|Pixel 3||Android 9 Pie||No|
|Pixel 3 XL||Android 9 Pie||No|
|Honor||Magic 2||Android 9 Pie||Yes|
|HTC||U12+||Android 8.0 Oreo||Yes|
|Huawei||Mate 20 X||Android 9 Pie||Yes|
|LG||G7 ThinQ||Android 8.0 Oreo||Yes|
|LG||V40 ThinQ||Android 8.1 Oreo||Yes|
|Motorola||Moto G4||Android 8.1 Oreo||No|
|Nokia||7.1||Android 8.1 Oreo||No|
|OnePlus||6||Android 8.1 Oreo/Android 9 Pie||Yes|
|OnePlus||6T||Android 9 Pie||Yes|
|Razer||Phone 2||Android 8.1 Oreo||Yes|
|Samsung||Galaxy Note 8||Android 8.0 Oreo||No|
|Samsung||Galaxy Note 9||Android 8.1 Oreo/Android 9 Pie||No|
|Samsung||Galaxy S7||Android 8.0 Oreo||No|
|Samsung||Galaxy S8||Android 8.0 Oreo||No|
|Samsung||Galaxy S9||Android 9 Pie||No|
|Samsung||Galaxy S9+ (Exynos)||Android 8.0 Oreo||Yes|
|Sony||Xperia XZ1||Android 9 Pie||No|
|Xiaomi||Mi Mix 2S||Android 9 Pie||Yes|
|Xiaomi||POCO F1||Android 8.1 Oreo||Yes|
How to check if your device is affected
It’s quite easy to check if your device is leaking process information to other apps (in other words, procfs is not mounted with hidepid=2). While you can use shell commands like we did, you can also check using an app that topjohnwu developed. His app also allows you to remount procfs with hidepid=2, if your phone is rooted.
Will there be a fix?
Yes, this will be fixed. Google will now be requiring that all devices mount procfs with hidepid=2. They will enforce this by updating the Compatibility Test Suite (CTS), a set of tests that all devices must pass to be able to use Google Play apps and services. All OEMs (that want to sell devices with the Google Play Store pre-installed) must eventually issue an update to remount procfs with hidepid=2 in the near future. Since OnePlus devices were the first to be discovered with this issue, OnePlus has already been made aware and is working on a fix. We’ll update this article if other OEMs comment on this bug, but there’s no need to wonder whether your device’s OEM will issue an update. If they want their update to pass CTS, then they must fix this bug.