¿POR QUÉ SE LE NIEGA EL ACCESO A ADB AL ALMACENAMIENTO MULTIUSUARIO?
Se le niega el acceso a /storage/emulated/10
desde adb shell
debido a este cambio en Android 9:
Agregar soporte "default_normal" a vold
.
Esta nueva bandera aísla a cada usuario en un dispositivo multiusuario por razones de seguridad.
Lo que hace la opción de montaje default_normal
en sdcardfs
se explica aquí:
_La opción default_normal
hace que los montajes con la gid establecida en AID_SDCARD_RW
tengan gids específicos de usuario, como en el caso normal._
Toda la historia se trata de la emulación del sistema de archivos de Android para tener un directorio sin permisos (/sdcard
) que permita compartir archivos entre múltiples usuarios (aplicaciones) UNIX. Se logra a través de espacios de nombre de montaje y diferentes VISTAS de /data/media
montadas en /mnt/runtime/
. Las aplicaciones pertenecientes a usuarios secundarios y primarios tienen espacios de nombre de montaje aislados. Para más detalles, consulte ¿Qué es el UID “u#_everybody”? y ¿Qué es /storage/emulated/0/?.
Por cierto, mi /sdcard/
siempre apunta al espacio del primer usuario /storage/emulated/0
en adb shell
, independientemente de cuál sea mi usuario actual en la interfaz móvil.
Para todos los procesos nativos que se ejecutan en el espacio de nombre de montaje root (incluido adbd
), /sdcard
es un enlace simbólico a /storage/emulated/0
y /storage/emulated
se monta por enlace desde /mnt/runtime/default
. Los archivos del propietario del dispositivo (User_ID: 0) en /storage/emulated/0
tienen propietario root:sdcard_rw (0:1015)
y modo de permiso 0771/storage/emulated/10
tienen propietario 0:1001015
.
Esto significa que los procesos que no son de root pueden leer los directorios solo si son miembros de grupos complementarios: 0001015
, 1001015
, 11001015
"otros" solo pueden atravesar los directorios. Dado que adbd
es miembro de solo 1015
GID, solo puede leer archivos del propietario del dispositivo, no de los usuarios secundarios.
Sin embargo, hasta Android 8 había una excepción a la regla anterior: para todos los procesos que se ejecutan en el espacio de nombre de montaje root (procesos que no son de aplicaciones), sdcardfs
siempre devolvía los directorios /storage/emulated/[N]
propiedad de GID 1015
. Por lo tanto, adb
podía leer estos directorios. Sin embargo, la excepción se eliminó en Android 9 utilizando la opción de montaje default_normal
.
¿CÓMO ACCEDER A ARCHIVOS DE MÚLTIPLES USUARIOS DESDE ADB
?
CON ACCESO DE ROOT:
Puede montar el sistema de archivos emulado sin la opción default_normal
:
~# umount /mnt/runtime/*/emulated
~# /system/bin/sdcard -u 1023 -g 1023 -m -w -G /data/media emulated
O para hacer cambios permanentes, reemplace el binario sdcard
con un script de shell:
~# cd /system/bin/; mv sdcard sdcard.bin; touch sdcard
~# chown 0.2000 sdcard*; chmod 0755 sdcard*
~# chcon u:object_r:system_file:s0 sdcard
~# chcon u:object_r:sdcardd_exec:s0 sdcard.bin
/system/bin/sdcard
(quitar el argumento -i
pasado por vold
):
#!/system/bin/sh
set -- $(echo "$*" | sed 's/-i //')
/system/bin/sdcard.bin $*
Después de reiniciar, debería poder leer archivos en /storage/emulated/10
desde adb shell
.
SIN ACCESO DE ROOT:
En Android 9+ nivel de sistema de archivos, el acceso a los perfiles/usuarios secundarios no es posible desde adb
en ROMs de compilaciones de usuario (es decir, sin root). Solo es posible la interacción a través de comandos de adb
que admiten la opción --user
(am
, pm
, content
, etc.). Documentado en What’s in Android 9 for enterprise apps:
"Para ayudar a mantener los datos laborales en el perfil laboral, la herramienta Android Debug Bridge (adb) no puede acceder a directorios y archivos en el perfil laboral."
Si los archivos propiedad de usuarios secundarios son accesibles para el usuario principal (a través de adb
o cualquier otro medio, excepto a través de la aplicación Controlador de Política de Dispositivo/Trabajo), se rompe el aislamiento previsto entre usuarios/perfiles que se controla a través de las API de Android. Vea más detalles en ¿Cómo compartir archivos entre una cuenta regular y una cuenta de trabajo?
Debe tenerse en cuenta que el Puente de Depuración de Android (adb
) está destinado a ser utilizado por desarrolladores para la depuración, no por usuarios finales. Es por eso que un propietario de dispositivo completamente administrado puede deshabilitar por completo adb
.
Hay una solución alternativa sugerida para transferir datos con usuarios/perfiles secundarios como se explica en Testing Multiple Users:
"adb
(o más precisamente el demonio adbd
) siempre se ejecuta como el usuario del sistema (ID de usuario = 0) independientemente de cuál sea el usuario actual. Por lo tanto, las rutas de dispositivo que dependen del usuario (como /sdcard/
) siempre se resuelven como el usuario del sistema."
...
"El acceso a rutas de /sdcard
de usuarios secundarios se deniega a partir de Android 9."
...
"Debido a que adb
se ejecuta como usuario del sistema y los datos están aislados en Android 9 y superior, debe usar proveedores de contenido para enviar o recibir datos de prueba de un usuario que no sea del sistema."
Por ejemplo, para transferir el archivo test.jpg
a /storage/emulated/10/Pictures/
ejecute los siguientes comandos desde adb shell
:
~$ contenido insertar --usuario 10 --uri content://media/external/images/media/ --bind _display_name:s:test.jpg
~$ ID=$(contenido consulta --usuario 10 --proyección _id --uri content://media/external/images/media/ --donde _display_name=\'test.jpg\' | grep -o '_id=[0-9]*' | cut -d= -f2)
~$ contenido escribir --usuario 10 --uri content://media/external/images/media/$ID < test.jpg
Sin embargo, no es un enfoque práctico para transferencias de datos a granel de forma regular.