TL; DR: Esta es una pregunta sobre el paso final, en un proceso de enraizamiento portátil orientado al desarrollador, que funciona en todas las máquinas Android. No se basa en ninguna hazaña: es algo que legal y moralmente podemos hacer, como desarrolladores, en nuestras propias máquinas. Si recibo una respuesta y logro hacer un chroot dentro de mi Debian, haré una publicación concisa en el blog que detallará todos los pasos de este proceso para todos los demás desarrolladores que desean acceso root a sus tabletas, y no quieren confiar en el origen dudoso "raíces de un clic" que hacen Dios sabe qué en sus máquinas (¿miembros de la botnet?) ... Las únicas dependencias serán las fuentes del núcleo de la máquina (que el fabricante está legalmente obligado a proporcionar) y la imagen de partición de arranque (boot.img
), que es el 99% de las veces dentro de las actualizaciones inalámbricas proporcionadas por el fabricante, o se puede descargar individualmente como una imagen independiente que se puede flashear.
Entonces, pasó una semana donde pasé todo mi tiempo libre en mi nueva tableta Android.
Y he tenido éxito casi por completo: en la creación de un proceso portátil orientado al desarrollador, para lograr la raíz en mi tableta Android 5.0.2.
Pero aún falta una cosa: no puedo hacer un chroot (¡lo que necesito para ejecutar mi debootstrap
Debian editado!)
Lo que hice hasta ahora
- Primero, hice un parche menor en las fuentes del núcleo de mi tableta (proporcionadas por el fabricante), y luego compilé mi propio núcleo, donde desactivé las comprobaciones para cambiar el modo de aplicación de SELINUX . Específicamente...
En 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,
Luego cambié mis imágenes initrd
/default.prop
para contener:ro.secure=0
yro.debuggable=1
Como a mi fabricante
initrd.img
le faltaba, también compilésu.c
desde https://android.googlesource.com/platform/system/extras/+/master/su/ y coloqué el binario resultante debajo/sbin/su
, asegurándome de que esté configurado como raíz SUID (chmod 04755 /sbin/su
) .
Después de eso, empaqueté el nuevo kernel y el nuevo initrd, como expliqué en el Episodio 2 de mi publicación anterior , y arranqué desde mi propia imagen:
adb reboot boot-loader ; fastboot boot myboot.img
Entonces, ¿eres root?
Sí, inicialmente parecía tener éxito:
$ 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
Y ahora he logrado 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
Estoy 100% seguro de que soy root, no solo porque lo id
dice, sino porque también puedo hacer cosas que los procesos normales definitivamente no pueden:
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)
He aquí que finalmente puedo leer particiones en bruto de mi tableta.
Y SELinux está realmente en modo "abajo, perro":
root@K01E_2:/ # getenforce
Permissive
Pero ... hay todavía cosas que no puedo hacer:
root@K01E_2:/ # mkdir /my_mnt
root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted
Es decir, no puedo montar mi segunda partición formateada EXT4-fs de mi tarjeta SD externa.
Tampoco puedo hacer chroot con mi debootstrap
Debian de encantadora lengua:
root@K01E_2:/ # chroot /data/debian/ /bin/bash
chroot() fail
Operation not permitted
¿Es por SELinux?
No sé, soy nuevo (muy nuevo, una semana) en SELinux. Pensé que cuando lo pones a dormir ( getenforce
informando "Permisivo") ya no interfiere ...
Aparentemente, estaba equivocado. Por la madriguera del conejo vamos de nuevo ...
¿Podría ser debido al contexto de mi proceso?
Recuerde que id
devolvió ... "uid = 0 (root) gid = 0 (root) ... context = u: r: shell: s0 "
¿Puedo cambiar ese contexto? Siendo root y todo, ¿puedo alejarme shell
? Y si es así, ¿pasar a qué?
La respuesta a la primera pregunta es 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
Bueno. Pero, ¿qué contexto me permitirá mount
y chroot
?
Leyendo un poco más sobre SELinux, de vuelta en mi máquina principal, analizo el /sepolicy
archivo en la raíz de 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, una serie de posibilidades! Especialmente ese kernel
parece prometedor:
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
Maldito.
¿Quién diablos me está bloqueando chroot
?
Cualquier consejo es bienvenido ...