Para poder correr bash
en el contexto de la aplicación de Termux para que se comporte exactamente de la misma manera que si se iniciara desde la aplicación, debe ser ejecutada al menos:
- Con el UID/GID de la aplicación asignado por el Administrador de Paquetes en el momento de la instalación
- Con un grupo suplementario
inet
( 3003
), que se requiere para crear enchufes de red y se asigna a cualquier aplicación en el momento de la instalación que declare android.permission.INTERNET
en su AndroidManifest.xml . Para más detalles ver ¿Cómo funciona el mapeo de permisos de Android con UIDs/GIDs? .
- Con un grupo suplementario
everybody
( 9997
) que se utiliza para controlar el acceso de lectura y escritura de la aplicación a /sdcard
. Para más detalles ver ¿Qué es el UID "u#_everybody"? .
- Con grupos suplementarios
<uid>_cache
(UID+10000) y all_<uid>
(UID+40000) para que la aplicación pueda acceder a su caché, código ejecutable nativo, etc. Pero esto no es necesario, ya que no estamos ejecutando la aplicación en sí.
- Al entrar en el espacio de nombres de la aplicación Termux (
com.termux
proceso) que se requiere para el supgid 9997
para trabajar. Si la aplicación no se está ejecutando (por ejemplo, si se está ejecutando desde adb shell
), supgid 1015
puede utilizarse para obtener acceso de escritura a /sdcard
pero no es así como funciona la aplicación.
- Dejando de lado todo Linux capacidades (privilegios de root granular en Efectivo , Permitido , Heredable , Límite y Ambiente sets) así como el ajuste
securebits
y el atributo de control del proceso NO_NEW_PRIVS que aseguran que la aplicación no pueda elevar los privilegios haciendo uso de setuid
o capacidades de archivo.
- Con bloqueado
syscalls
aplicando seccomp-bpf filtro.
- Con el contexto SELinux de la aplicación, que se determina en el tiempo de instalación / ejecución basado en MMAC ( 1 , 2 ) .
- Añadiendo el proceso a las cgroups por ejemplo.
cpuset
, memcg
etc. como lo hace el marco del Android.
- Por atrapando , bloqueando y ignorando el mismo señales como lo haría la aplicación.
- Al establecer el entorno en el que se basa. Por ejemplo, el golpe de Termux no se ejecutará sin
LD_LIBRARY_PATH
que requiere para la vinculación dinámica.
No hay una sola herramienta de línea de comandos disponible que pueda hacer todo esto, sólo se puede lograr completamente de forma programada (ver Minijail ), o podría estar utilizando múltiples herramientas, por ejemplo nsjail
/ firejail
para el ajuste seccomp
filtros, runcon
para cambiar el contexto de SELinux, capsh
para alterar las capacidades del DAC, nsenter
para entrar en el espacio de nombres de la montura, etc. setpriv
de util-linux
El paquete puede hacer el máximo:
~# uid=$(stat -c %u /data/data/com.termux)
~# pid=$(pidof -s com.termux)
~# label=$(cat /proc/$pid/attr/current)
~# export LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib
~# exec nsenter -t $pid -m setpriv --reuid $uid --regid $uid --groups 3003,9997 --bounding-set -all --selinux-label $label -- /system/bin/sh -c 'exec /data/data/com.termux/files/usr/bin/bash'
* nsenter
y setpriv
son applets de busybox pero con una funcionalidad limitada. Para aarch64
puede que haya binarios estáticos aquí: nsenter , setpriv .
Sin embargo, necesitamos definir shell_exec
(etiqueta de /system/bin/sh
) como entrypoint
para ser ejecutado por untrusted_app
contexto que no forma parte de las existencias sepolicy
(al menos en Pie):
~# supolicy --live 'allow untrusted_app shell_exec file entrypoint'
Ejecutando /system/bin/sh
antes de ejecutar /data/data/com.termux/files/usr/bin/bash
se requiere porque /data
La partición está montada con nosuid
que impide la transición del contexto de SELinux (de magisk
a untrusted_app
) ( 3 ) y se te niega el permiso. Puedes considerar montar /data
sin nosuid
para saltarse este paso.
Por la misma razón --no-new-privs
y --selinux-label
no puede ser usado en conjunto.
Todo esto sucede en el mundo nativo, nada en la pila de Java. Así que no tenemos control directo sobre cosas como permisos manifiestos que operan completamente dentro del marco de Android. Sin embargo, la aplicación de los permisos manifiestos también se basa en los UID ( 4 ) . Por ejemplo, si se concedió el Termux android.permission.WRITE_EXTERNAL_STORAGE
la fiesta que estamos llevando a cabo con el UID de Termux también será capaz de escribir a /sdcard
.
Por su comentario:
No tiene sentido para mí cómo es posible. Como, considera la salida:
u0_a129 ~$ /sbin/su --context=u:object_r:app_data_file:s0:c512,c768 u0_a129 -c /system/bin/id
uid=10129(u0_a129) gid=10129(u0_a129) groups=10129(u0_a129) context=u:r:magisk:s0
u0_a129 ~$ /system/bin/id
uid=10129(u0_a129) gid=10129(u0_a129) groups=10129(u0_a129),3003(inet),9997(everybody),20129(u0_a129_cache),50129(all_a129),99909997(u999_everybody) context=u:r:untrusted_app_27:s0:c512,c768
Según tengo entendido, así es como funciona el Control de Acceso Discrecional de Unix. En primer lugar, pasando --context
a Magisk's /sbin/su
no hace ninguna diferencia como se explica aquí :
la opción sigue existiendo para la compatibilidad de la CLI con las aplicaciones diseñadas para SuperSU. Sin embargo, la opción es silenciosamente ignorada ya que no es relevante.
Así que el contexto no está cambiado, como puedes ver, sigue siendo u:r:magisk:s0
. El segundo de los Magisk su
no es el verdadero usuario del interruptor ( 5 ) proporciona una funcionalidad mínima de la norma su
binario (el que tenemos en Linux). Para más detalles ver ¿Cómo funciona Magisk?
En su primer comando estableció UID, GID y grupos suplementarios al UID que usted proporcionó. No pediste su
para establecer cualquier grupo suplementario adicional, tampoco puede.
En el segundo comando se ve el UID, GID, grupos suplementarios y el contexto SELinxu que fueron establecidos por zygote
cuando se bifurcó el DVM/ART de la aplicación ( com.termux
en el caso de Termux). Los grupos suplementarios se explican más arriba. 99909997
también se explica en el enlace que se ha dado anteriormente.