6

Has a write-up ever been released on exactly how SuperSu works? After searching around for a while I found mostly guides on how to use the app, not the implementation details.

I did, however, find this resource that is mostly directed at explaining how to use the root privileges programmatically, but explained things fairly well. The article gives information about SELinux, but not so much how its enforcement is circumvented.

There appears to be a lot of context switching to allow execution of certain events (from the point of view of those using SuperSu) otherwise denied under SELinux, but how did SuperSu get to the point at which it was able to "legally", as far as SELinux is concerned, patch SELpolicies?

It seems that the objective is to force the init process to spawn a new shell that runs the su daemon, but there does not appear to be any patching of the init process, but from the article linked:

On firmwares that use SELinux, su is generally implemented as a proxy to a daemon started from init

and

You might wonder why - if we're already running as the init context, as the root user ..


tl;dr; How does SuperSu execute in the context of the init process?

Given as:

u:r:init:s0          - Highest init context
u:r:init_shell:s0    - Shell started from init
  • AFAIK, SuperSU only manages root permission. Without root access itself, SuperSU is useless (well, since there's no app that can use root access). On its Play Store, I don't see the app provides root access. – Andrew T. Jan 5 '16 at 16:24
  • @AndrewT, SuperSu is the name of the patch to Android that provides root access. The SuperSu APK downloaded from the appstore just manages it from a nice front-end, as you suggest. It, itself, leverages the already-present root accesses to do this, at at least this is how I understand it. – sherrellbc Jan 5 '16 at 16:25
  • i don't know exactly, but i can guess that it's merely owned by root:root and have setgid + setuid flags which allows anyone to execute supersu as root - at least that's how i would have implemented it ^^ – hanshenrik Oct 14 at 19:20
  • @hanshenrik Read No setuid/setgid programs and Restrict Setuid from Android Apps and Capability bounding and NO_NEW_PRIVS in Security Enhancements in Android 4.3 – Irfan Latif Oct 14 at 22:08
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.