Android asigna diferentes ID de usuario para cada aplicación instalada como un mecanismo de separación de privilegios. Esto puede verse afectado por el certificado que se utiliza para firmar una aplicación ( enlace ) junto con el atributo android:sharedUserId
en el archivo AndroidManifest.xml de la aplicación:
Cuando se instala una aplicación (archivo APK) en un dispositivo Android, el Administrador de paquetes verifica que el APK se haya firmado correctamente con el certificado incluido en ese APK. Si el certificado (o, más exactamente, la clave pública en el certificado) coincide con la clave utilizada para firmar cualquier otro APK en el dispositivo, el nuevo APK tiene la opción de especificar en el manifiesto que compartirá un UID con el otro similar -signados APKs.
Las aplicaciones de Android lanzadas por los usuarios finales se generan a partir del proceso Zygote (esto es para ayudar a acelerar el lanzamiento de la aplicación, ya que Zygote puede bifurcar y cargar el código de la aplicación y no tener que volver a cargar un montón de bibliotecas del sistema). En el momento de escribir esto, la configuración del servicio Zygote se ve así:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks
La sintaxis de este archivo se describe aquí: enlace , que tiene esto que decir acerca de los niveles de privilegios asignados a los servicios de forma predeterminada (para que pueda ver que, de forma predeterminada, Zygote se ejecuta como root):
user <username>
Change to username before exec'ing this service.
Currently defaults to root. (??? probably should default to nobody)
Currently, if your process requires linux capabilities then you cannot use
this command. You must instead request the capabilities in-process while
still root, and then drop to your desired uid.
Zygote usa un método JNI llamado forkAndSpecialize (busque " com_android_internal_os_Zygote.cpp
") para manejar la tarea específica de la plataforma de llamar setuid () al UID que el Package Manager ha asignado en función del manifiesto y las aplicaciones instaladas. Fallar en salir correctamente si esa llamada setuid falló ha sido la fuente de vulnerabilidades de la escalada de privilegios de Android en el pasado (lea sobre el exploit RageAgainstTheCage si está interesado, aunque eso no estaba relacionado con Zygote).
Esta es la razón principal por la que necesita un binario privilegiado / setuid separado para iniciar aplicaciones utilizando privilegios de nivel de raíz. Si construyes tu propia imagen personalizada del sistema, posiblemente podrías modificar el PackageManager / Zygote para conservar los privilegios de root, pero al hacerlo básicamente se rompe el modelo de seguridad de Android.