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 farFirst, 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 and ro.debuggable=1Since my manufacturer's initrd.img was missing it, I also compiled su.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.imgSo, are you root?Yes, it initially appeared to be successful:$ adb shellshell@K01E_2:/ $ iduid=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:s0shell@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/shexport PATH=/system/bin:$PATHexec /sbin/_su 0,0,1000,1028,2000,2001,1004,1007,1011,1015,\   1028,3001,3002,3003,3006And I have now achieved root:shell@K01E_2:/ $ suroot@K01E_2:/ # iduid=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:s0I 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/bootlrwxrwxrwx root root 2015-10-03 10:47 boot -> /dev/block/mmcblk0p16root@K01E_2:/ # dd if=/dev/block/mmcblk0p16 of=/dev/null bs=1M16+0 records in16+0 records out16777216 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                                                     PermissiveBut... there are still things I can't do:root@K01E_2:/ # mkdir /my_mntroot@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mntmount: Operation not permittedThat 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() failOperation not permittedIs 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/suroot@K01E_2:/ # iduid=0(root) gid=0(root)... context=u:r:debuggerd:s0Good. 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 chrootallow 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/suroot@K01E_2:/ # iduid=0(root) gid=0(root)... context=u:r:kernel:s0root@K01E_2:/ # chroot /data/debian/ /bin/bash                             chroot() failOperation not permittedDarn.Who the heck is blocking me from chrooting?Any advice most welcome...
SELinux and chroot system call
root;chroot;selinux
Who the heck is blocking me from chrooting?It wasn't SELinux - that was a wild goose chase (getenforce returning Permissive means that SELinux is indeed no longer in the picture).The culprit - after adding quite a number of printk in the kernel's source to trace the failures of both chroot and mount - turned out to be capabilities. More specifically, Android's capability bounding set - you can read all about them via your man (man 7 capabilities) and I confess I have never before bothered looking into them - my everyday UNIX tasks depended on them and I had no idea...  try this in your linux box to see for yourself:$ getfattr -d -m - /sbin/pinggetfattr: Removing leading '/' from absolute path names# file: sbin/pingsecurity.capability=0s......See? Ping is no longer SUID root - it uses information stored in the filesystem's extended attributes to know that it has access to the raw sockets layer (so it can do it's ICMP thing - at the IP level that is).Anyway, I digress - the surgery point in my kernel where I stopped the drop my capabilities set - in an arguably disgusting, let them all march in manner - was this (security/commoncap.c):static long cap_prctl_drop(struct cred *new, unsigned long cap){    if (!capable(CAP_SETPCAP))        return -EPERM;    if (!cap_valid(cap))        return -EINVAL;    // ttsiodras: come in, everyone, the water's fine!    //cap_lower(new->cap_bset, cap);    return 0;}This means that capabilities are NEVER dropped - a very secure configuration, indeed :-)$ adb shellshell@K01E_2:/ $ suroot@K01E_2:/ # chroot /data/debian/ /bin/bashroot@localhost:/# export PATH=/bin:/sbin:/usr/bin:/usr/sbin:\     /usr/local/bin:$PATHroot@localhost:/# cat /etc/issueDebian GNU/Linux 8 \n \lHello, my sweet Debian :-)Oh, and Root checker works, too - I snipped su.c, so everyone in my tablet can become root:int main(int argc, char **argv){  struct passwd *pw;  uid_t uid, myuid;  gid_t gid, gids[50];  /* Until we have something better, only root and shell can use su. */  myuid = getuid();  //  // ttsiodras - Oh no, you don't :-)  //  //if (myuid != AID_ROOT && myuid != AID_SHELL) {  //    fprintf(stderr,su: uid %d not allowed to su\n, myuid);  //    return 1;  //}Now that it works, I must make it work properly - i.e. allow only my termux and Terminal Emulator users to invoke su and chroot, and not let everyone and their grandmother in :-)