8 votes

Comment Android fait-il correspondre les autorisations avec les UIDs/GIDs ?

Lecture du livre : Android Security Internals que je lis au Chapitre 2 - Gestion des autorisations où il est indiqué que les autorisations sont attribuées à l'application au moment de l'installation par le gestionnaire de paquets avec un mapping comme UID de l'APK <-> Autorisations.

Plus tard dans le livre (Attribution des autorisations - Autorisations et attributs de processus paragraphe) j'ai lu que

Si des autorisations supplémentaires ont été attribuées à l'application, elles sont mappées sur des GIDs et attribuées en tant que GIDs supplémentaires au processus.

Et, puisque l'autorisation android.permission.INTERNET est associée au GID inet :

tout processus d'une application à laquelle la permission INTERNET a été accordée est associé au GID supplémentaire correspondant au groupe inet

Mais je me demandais si cela était toujours nécessaire.

En imaginant un cas où vous installez l'APK X déclarant la permission android.permission.INTERNET dans le AndroidManifest.xml, puisque le mappage des autorisations avec les UIDs est fait au moment de l'installation, le PackageManager devrait être capable de mapper directement l'autorisation avec l'UID de l'APK au lieu d'ajouter le GID inet à votre paquet APK. Je me demande donc pourquoi cela doit être ainsi :

tout processus d'une application à laquelle la permission INTERNET a été accordée est associé au GID supplémentaire correspondant au groupe inet

Est-ce que quelqu'un pourrait m'éclairer sur ce point ?

0 votes

C'est simplement la façon dont cela fonctionne. Vérifier si un utilisateur est membre d'un groupe spécifique est beaucoup plus simple que de devoir vérifier à chaque demande si un utilisateur est autorisé à ceci ou à cela.

12voto

Irfan Latif Points 16863

La gestion des autorisations d'Android peut être divisée en deux parties : le noyau Linux et le cadre Android.

LE CONTRÔLE D'ACCÈS DISCRÉTIONNAIRE :

Le contrôle d'accès discrétionnaire (CAD) basé sur les utilisateurs, les groupes et le mode d'accès remonte aux premiers jours d'UNIX. Chaque fichier (y compris les répertoires) et chaque processus a un utilisateur propriétaire (UID) et un groupe propriétaire (GID). Ainsi, un processus est autorisé à lire, écrire et exécuter une ressource en fonction de ses bits de mode d'accès ( RWX ) pour les utilisateurs, les groupes et autres ( UGO ). Ces attributs de permissions sont enregistrés avec les fichiers dans le système de fichiers.
UID/GID 0 est spécial pour le noyau Linux ; c'est le super utilisateur (administrateur) qui n'est jamais empêché de faire quoi que ce soit. Tous les autres utilisateurs de la gamme 1-65534 sont des identifiants non privilégiés qu'un système d'exploitation peut utiliser de la manière qu'il souhaite pour contrôler l'accès.

Android réserve des UIDs dans la gamme 1000-9999 pour l'utilisation du système, contrairement aux distros Linux où 1000 est généralement le premier UID attribué aux utilisateurs humains. Android est conçu pour un seul utilisateur humain mais chaque application Java, qu'elle soit préinstallée (en tant qu'application système ou utilisateur) ou installée par l'utilisateur, est traitée comme un utilisateur. Plage d'UID 10000-19999 est réservé à ces applications. Au premier démarrage (pour les applications préinstallées) ou lors de l'installation d'une nouvelle application, un UID/GID unique est attribué à l'application, qui reste statique sauf si l'application est désinstallée. Cette correspondance entre l'application et l'UID peut être vue dans le fichier /data/system/packages.list ou en utilisant la commande id ( 1 ) si l'application fournit un shell ou peut exécuter des binaires natifs.

Tous ces UID ont des noms codés en dur dans Android, à savoir prédéfini Contrairement aux distributions Linux, où il y a presque toujours une norme conventions de dénomination pour les utilisateurs et les groupes qui peuvent être ajoutés/supprimés dans la base de données de l'UE. /etc/passwd y /etc/group . Android ne partage que root nom d'utilisateur avec Linux. Cependant, ces noms ne servent qu'à faciliter la tâche des utilisateurs humains. Pour le noyau, seuls les numéros (UID/GID) ont une signification.

Listes de contrôle d'accès ( ACLs ) peuvent être utilisés pour étendre le DAC pour des privilèges plus granulaires mais ils sont rarement utilisés sous Linux et (AFAIK) pas sous Android.

LES CAPACITÉS DE LINUX :

Les autorités de l'utilisateur racine sont encore divisées en sous-groupes appelés capacités . Au lieu d'utiliser l'UID 0 chaque fois qu'une tâche élevée doit être exécutée, un UID non privilégié peut se voir accorder uniquement la capacité requise. Les capacités de fichiers qui sont attachées aux fichiers en utilisant les Attributs Étendus ( XATTR ), peut également être utilisé pour élever les capacités du processus lorsque cela est nécessaire. Android utilise Capacités des fichiers ainsi que Capacités ambiantes . Voir ce fil pour plus de détails.

LE CONTRÔLE D'ACCÈS OBLIGATOIRE :

Le contrôle d'accès obligatoire (MAC) a été introduit plus tard pour compléter le DAC pour une meilleure sécurité. Android utilise SELinux dans le cadre de son les applications de sécurité . SELinux utilise également les attributs étendus pour étiqueter les fichiers avec un contexte, tandis que chaque processus est également exécuté avec un contexte SELinux. Ensuite, une politique est définie qui comprend des milliers de règles permettant à un contexte d'accéder à l'autre, refusé autrement par défaut. Voir cette réponse pour plus de détails sur SELinux et un exemple de la manière dont Android utilise les DAC, capabilities et MAC.

En utilisant le DAC, le MAC et les capacités du noyau Linux, Android lance chaque application dans une machine virtuelle sandboxée, issue d'une bifurcation du noyau Linux. zygote avec son ID unique et avec toutes les capacités supprimées, de sorte qu'il est forcé d'accéder uniquement à ses propres fichiers dans la base de données de l'UE. /data/data/<app_pkg_name> ou dans un stockage externe. Voir cette réponse pour plus de détails.

LES AUTORISATIONS MANIFESTES :

Afin d'avoir un contrôle plus fin des ressources du système, en plus des mécanismes de contrôle d'accès de Linux au niveau du noyau, Android applique son propre système de contrôle d'accès. Permissions du manifeste aux applications installées dans son cadre principal. Ces permissions sont de trois types : Normal, Dangereux et Signature.
Toutes les autorisations normales sont accordées à un demande d'application sans interaction humaine. Par exemple, un utilisateur ne peut pas empêcher une application d'accéder à l'internet si l'application demande android.permission.INTERNET . Certaines de ces autorisations sont contrôlées à l'aide d'outils tiers.
Les autorisations dangereuses, telles que READ_CONTACTS - ne sont pas accordées à une application sans l'approbation de l'utilisateur. Certains des Autorisations de signature traité comme Permissions spéciales - comme REQUEST_INSTALL_PACKAGES - peut également être contrôlé à partir de Settings app > Apps & notifications > Advanced > Special app access sur les versions Android les plus récentes.
En outre, certaines des autorisations pour lesquelles l'utilisateur n'a pas de contrôle indépendant, telles que GET_ACCOUNTS ou les opérations qui n'ont pas de permissions correspondantes telles que RUN_IN_BACKGROUND peut être contrôlé à partir d'un gestionnaire de permissions caché d'Android : AppOps . Mais cela n'est destiné qu'à l'utilisation du système d'exploitation et non aux utilisateurs finaux.

VÉRIFICATION ET APPLICATION DES AUTORISATIONS :

Les préférences de permission sont stockées par le gestionnaire de paquets Android dans différents fichiers tels que /data/system/packages.list , /data/system/packages.xml , /data/system/users/0/runtime-permissions.xml au moment de l'installation de l'application ou au moment de l'exécution. Ces contrôles de permission sont ensuite appliqué à plusieurs événements par exemple lors de l'accès à des intentions, du lancement d'une activité, de l'envoi/réception de diffusions, de l'accès à un fournisseur de contenu, du lancement/de la liaison à un service, etc.

Bien que l'ensemble processus de vérification et d'application des autorisations se passe sous zygote dans laquelle ActivityManager y PackageManager - qui font partie de system_server - jouent un rôle majeur, le cadre de base ne gère pas tout seul la vérification des autorisations. Il prend à nouveau l'aide du noyau pour rendre les contrôles de permission plus robustes et efficaces.
Par exemple LECTURE/ÉCRITURE_MAGASIN EXTERNE Les permissions sont appliquées par le biais d'UIDs/GIDs en liant le montage de différentes vues de Stockage dans un espace de nom de montage pour chaque application. Voir cette réponse pour plus de détails.

PERMISSION <--> GID MAPPING :

Un autre cas particulier où Android s'appuie sur le noyau Linux pour la vérification des autorisations est le suivant android.permission.INTERNET . Comme indiqué précédemment, seuls les UID/GID 0 est spécial pour le noyau standard de Linux. Cependant Android a appliqué un patch spécial PARANOÏAQUE_RÉSEAU au noyau Linux qui fait correspondre certaines capacités à certaines identifiants de groupe dans la gamme 3000-3999 en les rendant spéciaux. L'un d'entre eux est INET (3003) qui permet à ses membres d'accéder à l'internet (créer des sockets PACKET), ce qui n'est pas possible sans cette capacité. NET_RAW autrement. Tous les sites permission <-> GID Les mappings peuvent être trouvés dans le fichier /system/etc/permissions/platform.xml .

Pour en venir à votre question :

puisque le mappage des permissions avec les UIDs est fait au moment de l'installation, PackageManager devrait pouvoir mapper la permission directement avec l'UID de l'APK au lieu d'ajouter le GID inet à votre paquet APK.

Donc la réponse est, PackageManager ne gère pas android.permission.INTERNET par lui-même. Il ajoute simplement l'application au groupe INET et enregistre la configuration. Prenons l'exemple de Termux :

~# grep termux /data/system/packages.list
com.termux 10142 0 /data/user/0/com.termux default:targetSdkVersion=28 3003

La prochaine fois que l'application sera lancée avec 3003 dans ses groupes supplémentaires, le noyau n'empêchera pas l'application d'accéder à Internet lors de l'application du DAC :

~# ps -p $(pgrep com.termux) -o cmd,uid,gid,supgrp
CMD                           UID   GID SUPGRP
com.termux                  10142 10142 3003,9997,20142,50142

SOURCES :

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X