La gestión de permisos de Android puede dividirse principalmente en dos partes: El kernel de Linux y el framework de Android.
CONTROL DE ACCESO DISCRECIONAL:
El control de acceso discrecional (DAC) basado en usuarios, grupos y modo de acceso se remonta a los primeros días de UNIX. Cada archivo (incluidos los directorios) y proceso tiene un propietario de usuario (UID) y un propietario de grupo (GID). Así, un proceso puede leer, escribir y ejecutar un recurso dependiendo de los bits de su modo de acceso ( RWX
) para Usuario, Grupo y Otros ( UGO
). Estos atributos de permisos se guardan junto con los archivos en el sistema de archivos.
UID/GID 0
es especial para el kernel de Linux; es el súper usuario (administrador) al que nunca se le niega hacer nada. Todos los demás usuarios en el rango 1-65534
son identificaciones no privilegiadas que un SO puede utilizar de la manera que quiera para controlar el acceso.
Android reserva UIDs en el rango 1000-9999
para el uso del sistema, a diferencia de las distribuciones de Linux, donde el 1000 suele ser el primer UID asignado a los usuarios humanos. Android está diseñado para un solo usuario humano, pero cada aplicación Java, ya sea preinstalada (como aplicación de sistema o de usuario) o instalada por el usuario, es tratada como un usuario. Rango de UIDs 10000-19999
está reservado para estas aplicaciones. En el primer arranque (para las aplicaciones preinstaladas) o cuando se instala una nueva aplicación, se asigna un UID/GID único a la aplicación que es estático a menos que la aplicación se desinstale. Este mapeo de app vs. UID puede verse en el archivo /data/system/packages.list
o utilizando el comando id
( 1 ) si la aplicación proporciona un shell o puede ejecutar binarios nativos.
Todos estos UID tienen nombres codificados en Android que son predefinido A diferencia de las distribuciones de Linux, en las que existen convenciones de nomenclatura para los usuarios y grupos que se pueden añadir/eliminar en /etc/passwd
y /etc/group
. Android sólo comparte root
nombre de usuario con Linux. Sin embargo, estos nombres son sólo para la facilidad de los usuarios humanos, para el kernel sólo significan números (UID/GID).
Listas de control de acceso ( ACLs ) se puede utilizar para ampliar el DAC para obtener privilegios más granulares, pero estos se utilizan raramente en Linux y (AFAIK) no se utilizan en Android.
CAPACIDADES DE LINUX:
Las autoridades del usuario root se dividen a su vez en subgrupos denominados capacidades . En lugar de utilizar el UID 0 siempre que se vaya a realizar una tarea elevada, se puede conceder a un UID sin privilegios sólo la capacidad requerida. Las capacidades de archivo que se adjuntan a los archivos mediante atributos extendidos ( XATTR ), también se puede utilizar para elevar las capacidades del proceso siempre que sea necesario. Android hace uso de Capacidades de los archivos así como Capacidades ambientales . Ver este hilo para más detalles.
CONTROL DE ACCESO OBLIGATORIO:
El Control de Acceso Obligatorio (MAC) se introdujo posteriormente para complementar el DAC y mejorar la seguridad. Android utiliza SELinux como parte de su aplicaciones de seguridad . SELinux también hace uso de los Atributos Extendidos para etiquetar archivos con un contexto mientras que cada proceso también se ejecuta con un contexto SELinux. Entonces se define una política que incluye miles de reglas que permiten el acceso de un contexto a otro, denegado por defecto. Ver esta respuesta para más detalles sobre SELinux y un ejemplo de cómo Android hace uso de DAC, capabilities y MAC.
Haciendo uso del DAC, MAC y las capacidades del kernel de Linux, Android lanza cada aplicación en una máquina virtual de sandboxing bifurcada de zygote
con su ID único y con todas las capacidades eliminadas, de modo que se vea obligado a acceder sólo a sus propios archivos en /data/data/<app_pkg_name>
o en un almacenamiento externo. Ver esta respuesta para más detalles.
PERMISOS MANIFIESTOS:
Para tener un control más fino de los recursos del sistema, además de los mecanismos de control de acceso de Linux a nivel del núcleo, Android aplica su propio Permisos del Manifiesto a las aplicaciones instaladas dentro de su marco central. Estos permisos son de tres tipos : Normal, Peligroso y Firma.
Todos los permisos normales se conceden a un solicitando la aplicación sin interacción humana. Por ejemplo, un usuario no puede restringir el acceso a Internet de una aplicación si ésta solicita android.permission.INTERNET
. Algunos de estos permisos se controlan utilizando herramientas de terceros.
Permisos peligrosos - como READ_CONTACTS
- no se conceden a una aplicación sin la aprobación del usuario. Algunas de las Permisos de firma tratado como Permisos especiales - como REQUEST_INSTALL_PACKAGES
- también se puede controlar desde Settings app > Apps & notifications > Advanced > Special app access
en las nuevas versiones de Android.
Además, algunos de los permisos para los que el usuario no tiene control independiente, como GET_ACCOUNTS o las operaciones que no tienen permisos correspondientes como RUN_IN_BACKGROUND , se puede controlar desde un gestor de permisos oculto de Android: AppOps . Pero esto está pensado sólo para el uso del sistema operativo y no para los usuarios finales.
COMPROBACIÓN Y APLICACIÓN DE PERMISOS:
Las preferencias de permisos son almacenadas por Android Package Manager en diferentes archivos como /data/system/packages.list
, /data/system/packages.xml
, /data/system/users/0/runtime-permissions.xml
en el momento de la instalación de la aplicación o en tiempo de ejecución. Estas comprobaciones de permisos son entonces se aplica en múltiples eventos como cuando se accede a los intentos, se inicia una actividad, se envía/recibe una emisión, se accede a un proveedor de contenidos, se inicia/se vincula a un servicio, etc.
Aunque todo el proceso de comprobación y aplicación de permisos sucede en zygote
en el que ActivityManager y PackageManager - que forman parte de system_server
- juegan un papel importante, el núcleo de la estructura no maneja todas las comprobaciones de permisos por sí mismo. Una vez más, necesita la ayuda del núcleo para que las comprobaciones de permisos sean más robustas y eficientes.
Por ejemplo LEER/ESCRIBIR_ALMACENAMIENTO_EXTERNO Los permisos se imponen a través de UIDs/GIDs mediante el montaje de diferentes vistas de Almacenamiento en un espacio de nombres de montaje para cada aplicación. Ver esta respuesta para más detalles.
PERMISO <--> MAPEO GID:
Otro caso especial en el que Android se apoya en el kernel de Linux para la comprobación de permisos es android.permission.INTERNET
. Como ya se ha dicho, sólo el UID/GID 0
es especial para el núcleo estándar de Linux. Sin embargo Android aplicó un parche especial PARANOID_NETWORKING al kernel de Linux que asigna ciertas capacidades a ciertos identificaciones de grupo en el rango 3000-3999
haciéndolos especiales. Uno de ellos es INET (3003) que permite a sus miembros acceder a Internet (crear sockets PACKET) lo que no es posible sin la capacidad NET_RAW de lo contrario. Todos los permission <-> GID
Las asignaciones pueden encontrarse en el archivo /sistema/etc/permisos/plataforma.xml .
Pasando a su pregunta:
ya que la asignación de permisos con UIDs se realiza en el momento de la instalación, PackageManager debería ser capaz de asignar el permiso directamente con el UID del APK en lugar de añadir el GID de inet a su paquete APK
Así que la respuesta es, PackageManager
no maneja android.permission.INTERNET
por su cuenta. Sólo añade la aplicación al grupo INET y guarda la configuración. Tomemos el ejemplo de Termux:
~# grep termux /data/system/packages.list
com.termux 10142 0 /data/user/0/com.termux default:targetSdkVersion=28 3003
La próxima vez que se lance la aplicación con 3003 en sus grupos suplementarios para que el kernel no restrinja el acceso a internet de la aplicación al aplicar el DAC:
~# ps -p $(pgrep com.termux) -o cmd,uid,gid,supgrp
CMD UID GID SUPGRP
com.termux 10142 10142 3003,9997,20142,50142
FUENTES:
0 votos
Así es simplemente como funciona. Comprobar si un usuario es miembro de un grupo específico es mucho más sencillo que en cada petición tener que comprobar si un usuario está autorizado a esto y aquello.