SuperSU is no more actively developed, the new prevailing standard is Magisk which was originally based on SuperSU (ideas and perhaps some code too) but now it has moved far ahead. So better go for a new actively maintained open-source solution wherever possible. Or if you want some adventure, try this: How to manually root a phone?.
My answer to How Magisk works? covers almost all internals of SuperSU, also some extra details which aren't applicable to SuperSU. Let's keep it simple.
ROOT USER (UID 0
):
Android is based on Linux kernel which, when starts at device boot, runs as root user. Kernel space is invisible to us - the userspace. init
is the first process started by kernel which we can see, it also runs with root access. It starts many services/daemons (the OS), many of them also run with root privileges. Finally when all required processes are up, init
drops us to a non-root (unprivileged) process - a shell on standard Linux OSes, a Launcher app or Lock Screen (which is also System UI app) on Android. Root is kernel's dear user - the Super User - identified by UserID 0
. Kernel never restricts him doing any harm or good to anything on device. Non-privileged users are assigned UIDs 1
to 65534
(usually). Android divides these UIDs for different categories of apps and processes as explained here. Every process and every file has a UID, GroupID, supplementary groups and permission mode. These four parameters govern how a process accesses other processes and files. This whole phenomenon is called Discretionary Access Control.
HOW APPS GET ROOT ACCESS?
If an unprivileged process wants to access some file or perform some action which is only allowed to root user, the former has to switch to the latter. It's done by executing a file (usually su
) which is either set-user-id-root or has setuid
/segid
file capabilities. A capability is a subset of root user's authorities. Executed file makes setuid
syscall so the kernel elevates unprivileged state to privileged. This is a simplification, in actual there are multiple other factors involved. But on Android, apps are run by dropping all capabilities and privileges in such a way that they can't elevate their privileges in any way (excluding vulnerabilities). So the unprivileged app requests some other already running privileged process to perform the privileged task on former's behalf. The privileged process is named daemonsu
(or magiskd
) and the request is forwarded when an app executes special su
binary which interacts with SuperSU app to ask the human user for granting permission.
SELINUX:
In addition to DAC, Android also makes use of SELinux - a Mandatory Access Control. Like DAC, every process and every file is labeled with a SELinux context and a policy is defined to allow a wide range of interactions between contexts/labels. Policy contains no Super Context, so every process (even running with UID 0
) has some limitations. But daemonsu
needs to be run with a completely unrestricted context which has to be defined before SELinux is set enforcing
(by init
at very early boot stage) because after that there is no way to set it permissive
or modify policy. Some vendors build their kernels without SECURITY_SELINUX_DEVELOP
, so SELinux is enforced by kernel - even earlier. In this case kernel needs to be rebuilt/patched. See details in this answer.
ROOTING PROCESS
When SuperSU.zip is flashed:
- It patches
/sepolicy
file with fully permissive u:r:supersu:s0
context (supersu
can be different, I can't recall what SuperSU used in last releases, Magisk now uses u:r:magisk:s0
).
- It injects a custom
init
service to /init.rc
file which starts daemonsu
with UID/GID 0
and SELinux context u:r:supersu:s0
after /data
is mounted (or even before).
Both sepolicy
and init.rc
files have been part of ramdisk
inside boot.img
(which also contains kernel binary), but with Treble, SAR and A/B
Partitions they might be on different locations. So Magisk uses different approaches for different devices but the concept is same.
Both steps may also be substituted by replacing the actual /init
binary with a custom init
which takes over boot process, patches sepolicy
and starts service on the go before executing actual init
.
Other things which are directly related to rooting process include bootloader unlocking, boot.img
unpacking/repacking, disabling Verified Boot (dm-verity
) and FDE/FBE, patching kernel to boot different init
(or to disable vendor specific security mechanisms), systemless rooting, (un)setting Android properties, bind-mounting directories, isolating mount namespaces etc.