Every couple of months the question is asked to the OWNERS: “How does adb root/unroot work?”. Every time, we have to dig out the code to remember. Here is a doc to hopefully solve this problem.
adbd
always starts running as user root
. One of the first things the daemon does is to check if it should drop its privileges to run as shell
user. There are a few read-only properties involved in the decision.
ro.secure ro.debuggable
On a user
debug, these properties will never allow adbd
to remain root
. However, on eng
and userdebug
builds they will.
If adbd can remain root
, it doesn't mean that it should. There is a second level decision dictated by the property service.adb.root
. If set to 1
, adbd remains root
. Otherwise, it drops to shell
.
The command adb root
and adb unroot
triggers adbd to write service.adb.root
and restart.
The one catch is that adbd
cannot call exit(3)
right away since it must make sure the “success” message makes it back to the caller on the host.
The trick is done by tagging any asocket associated with a root
/unroot
command to call exit(3)
when the asocket they run upon is closed (see exit_on_close
).
If adbd
calls exit(3)
, how does it restart itself? Since it is a critical process, initd
notices that it is gone and restarts it.