I've read in another answer that on Android the su binaries avoid needing to be setuid by using filesystem capabilities like cap_setuid. But then I tried to check this, and to my surprise, I found no capabilities set on my Magisk-enabled Android 8.0 system.

Here's how I checked:

  1. Logged in via SimpleSSHD
  2. scp'ed the following binaries taken from Debian arm64 packages libcap2, libcap2-bin and libc6:
    • getcap
    • libc.so.6
    • libcap.so.2.25
    • libcap.so.2
    • ld-2.27.so
  3. Had the following terminal session on the phone:

$ su
# whoami
# exit

$ type su
su is /sbin/su

$ ls -lh /sbin/su
lrwxrwxrwx 1 root root 12 2018-08-12 22:40 /sbin/su -> /sbin/magisk

$ ls -lh /sbin/magisk
-rwxr-xr-x 1 root root 94 2018-08-12 22:40 /sbin/magisk

$ sed 's@^@> @' /sbin/magisk
> #!/system/bin/sh
> unset LD_PRELOAD
> exec /sbin/magisk.bin "${0##*/}" "$@"

$ ls -lh /sbin/magisk.bin
-rwxr-xr-x 1 root root 71K 2018-08-12 22:40 /sbin/magisk.bin

$ file /sbin/magisk.bin
/sbin/magisk.bin: ELF shared object, 32-bit LSB arm, dynamic (/system/bin/linker), stripped

$ LD_LIBRARY_PATH=. ./ld-2.27.so ./getcap -v /sbin/magisk.bin

As you can see, neither setuid bit, nor any capabilities are present in the /sbin/magisk.bin binary. So what's going on? How does it work?


It appears that /sbin/magisk.bin the non-root user launches doesn't spawn the root shell by itself. Instead, it communicates its request to magiskd, which is executed as root. And magiskd, after checking for permissions, executes the command requested. (Interestingly, magiskd is the same binary – /sbin/magisk.bin, but run by init as root).

You can check this as follows:

$ echo $$

$ su

# echo $PPID

# exit

$ su

# echo $PPID

# ps -A|egrep '^[^ ]+ +2606'
root          2606     1   16044   2068 __skb_recv_datagram eb4d2fe0 S magiskd

Note that in the output above, after we exit the superuser shell and re-enter it, parent PID still remains the same (2606 in this session), but not equal to the PID of the original non-root shell (27699 in this session). Moreover, parent PID of magiskd is 1, i.e. init, which is one more confirmation that it's not what we started from our non-root shell.

  • It looks like /sbin/magisk.bin is designed like Busybox... essentially, an executable library of commands (at least 2 in this case). The code chooses which to execute based on the symlink it was invoked through. That can be done with bash scripts too. – DocSalvager Aug 16 '18 at 8:42

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.