TL; DR: This is a question about the final step, in a portable, developer-oriented rooting process, that works across all Android machines. It is not based on any exploit - it is something that we are legally and morally allowed to do, as developers, to our own machines. If I get an answer and manage to chroot inside my Debian, I will make a concise blog post detailing all the steps of this process for all the fellow developers that want root access to their tablets - and don't want to trust dubious-origin "one-click-roots" that do God-knows-what to their machines (botnet members?)... The only dependencies will be the machine's kernel sources (which the manufacturer is legally obligated to provide) and the boot partition image (boot.img
), which is 99% of the times inside the manufacturer-provided Over-the-air updates, or individually downloadable as a standalone flash-able image.
So, a week passed where I spent all my free time on my new Android tablet.
And I have almost completely succeeded - in creating a portable, developer-oriented process, for achieving root in my Android 5.0.2 tablet.
But there's one thing missing yet - I can't do a chroot (which I need to run my debootstrap
-ed Debian!)
What I did so far
- First, I did a minor patch in my tablet's (manufacturer-provided) kernel sources, and then compiled my own kernel - where I disabled the checks for changing SELINUX enforcing mode. Specifically...
In security/selinux/selinuxfs.c
:
...
if (new_value != selinux_enforcing) {
/* Commented out by ttsiodras.
length = task_has_security(current, SECURITY__SETENFORCE);
if (length)
goto out;
*/
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
new_value, selinux_enforcing,
I then changed my initrd image's
/default.prop
to contain:ro.secure=0
andro.debuggable=1
Since my manufacturer's
initrd.img
was missing it, I also compiledsu.c
from https://android.googlesource.com/platform/system/extras/+/master/su/ and placed the resulting binary under/sbin
, making sure it is set to SUID root (chmod 04755 /sbin/su
).
After that, I packaged the new kernel and the new initrd, as I explained in Episode 2 of my previous post - and booted from my own image:
adb reboot boot-loader ; fastboot boot myboot.img
So, are you root?
Yes, it initially appeared to be successful:
$ adb shell
shell@K01E_2:/ $ id
uid=2000(shell) gid=2000(shell) groups=1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),
3003(inet),3006(net_bw_stats)
context=u:r:shell:s0
shell@K01E_2:/ $ ls -l /sbin/su /sbin/_su
-rwxr-xr-x root root 131 2015-10-03 10:44 su
-rwsr-xr-x root root 9420 2015-10-03 01:31 _su
(the _su is the binary I compiled, set to SUID root, and "su" is
a script I wrote to tell "su" to add me to all these groups...)
shell@K01E_2:/ $ cat /sbin/su
#!/system/bin/sh
export PATH=/system/bin:$PATH
exec /sbin/_su 0,0,1000,1028,2000,2001,1004,1007,1011,1015,\
1028,3001,3002,3003,3006
And I have now achieved root:
shell@K01E_2:/ $ su
root@K01E_2:/ # id
uid=0(root) gid=0(root)
groups=1000(system),1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),1028(sdcard_r),2000(shell),2001(cache),
3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats)
context=u:r:shell:s0
I am 100% sure I am root - not only because id
says so, but because I can also do things that normal processes definitely can't:
root@K01E_2:/ # ls -l /dev/block/platform/msm_sdcc.1/by-name/boot
lrwxrwxrwx root root 2015-10-03 10:47 boot -> /dev/block/mmcblk0p16
root@K01E_2:/ # dd if=/dev/block/mmcblk0p16 of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes transferred in 0.569 secs (29485441 bytes/sec)
Lo and behold - I can finally read raw partitions out of my tablet!
And SELinux is indeed in "down, dog" mode:
root@K01E_2:/ # getenforce
Permissive
But... there are still things I can't do:
root@K01E_2:/ # mkdir /my_mnt
root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted
That is, I can't mount my EXT4-fs formatted 2nd partition of my external SD card.
I also can't chroot to my lovely debootstrap
-ed Debian:
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
Is it because of SELinux?
I don't know - I am new (very new - one week old) to SELinux. I thought that when you put it to sleep (getenforce
reporting "Permissive") it no longer interferes...
Apparently, I was wrong. Down the rabbit hole we go again...
Could it be because of my process context?
Remember that id
returned... "uid=0(root) gid=0(root)... context=u:r:shell:s0"
Can I change that context? Being root and all, can I move away from shell
? And if so, move to what?
The answer to the first question is runcon
:
shell@K01E_2:/ $ runcon u:r:debuggerd:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:debuggerd:s0
Good. But what context will allow me to mount
and chroot
?
Reading some more about SELinux, back in my main machine, I parse the /sepolicy
file on the root of the initrd.img
:
linuxbox$ $ sesearch -A sepolicy | grep chroot
allow init_shell init_shell : capability { chown sys_chroot ...
allow init init : capability { chown dac_read_search sys_chroot ...
allow kernel kernel : capability { chown dac_override sys_chroot ...
allow asus-dbug-d asus-dbug-d : capability { chown sys_chroot ...
...
OK, a number of possibilities! Especially that kernel
one seems promising:
shell@K01E_2:/ $ runcon u:r:kernel:s0 /sbin/su
root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:kernel:s0
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
Darn.
Who the heck is blocking me from chroot
ing?
Any advice most welcome...