Consultez cette page pour vous familiariser avec les concepts de SELinux.
Contrôle d'accès obligatoire
Security Enhanced Linux (SELinux) est un système de contrôle d'accès obligatoire (MAC) pour le système d'exploitation Linux. En tant que système MAC, il diffère du système de contrôle d'accès discrétionnaire (DAC) familier de Linux. Dans un système DAC, un concept de propriété existe, selon lequel un propriétaire d'une ressource particulière contrôle les autorisations d'accès qui lui sont associées. Ceci est généralement grossier et sujet à une élévation involontaire des privilèges. Un système MAC, cependant, consulte une autorité centrale pour une décision sur toutes les tentatives d'accès.
SELinux a été implémenté dans le cadre du framework Linux Security Module (LSM), qui reconnaît divers objets du noyau et les actions sensibles effectuées sur eux. Au moment où chacune de ces actions serait exécutée, une fonction de crochet LSM est appelée pour déterminer si l'action doit être autorisée ou non sur la base des informations la concernant stockées dans un objet de sécurité opaque. SELinux fournit une implémentation pour ces crochets et la gestion de ces objets de sécurité, qui se combinent avec sa propre politique, pour déterminer les décisions d'accès.
Avec d'autres mesures de sécurité Android, la politique de contrôle d'accès d'Android limite considérablement les dommages potentiels des machines et des comptes compromis. L'utilisation d'outils tels que les contrôles d'accès discrétionnaires et obligatoires d'Android vous donne une structure pour vous assurer que votre logiciel ne fonctionne qu'au niveau de privilège minimum. Cela atténue les effets des attaques et réduit la probabilité que des processus errants écrasent ou même transmettent des données.
Dans Android 4.3 et versions ultérieures, SELinux fournit un parapluie de contrôle d'accès obligatoire (MAC) sur les environnements de contrôle d'accès discrétionnaire (DAC) traditionnels. Par exemple, le logiciel doit généralement s'exécuter en tant que compte d'utilisateur root pour écrire sur des périphériques de bloc bruts. Dans un environnement Linux traditionnel basé sur DAC, si l'utilisateur racine est compromis, cet utilisateur peut écrire sur chaque périphérique de bloc brut. Cependant, SELinux peut être utilisé pour étiqueter ces périphériques afin que le processus auquel le privilège root est attribué ne puisse écrire que sur ceux spécifiés dans la stratégie associée. De cette manière, le processus ne peut pas écraser les données et les paramètres système en dehors du périphérique de bloc brut spécifique.
Voir Cas d'utilisation pour plus d'exemples de menaces et de moyens de les traiter avec SELinux.
Niveaux d'application
SELinux peut être implémenté dans différents modes :
- Permissive - La politique de sécurité SELinux n'est pas appliquée, seulement enregistrée.
- Application - La politique de sécurité est appliquée et consignée. Les échecs apparaissent comme des erreurs EPERM.
Ce choix est binaire et détermine si votre stratégie agit ou vous permet simplement de recueillir des échecs potentiels. La permission est particulièrement utile lors de la mise en œuvre.
Types, attributs et règles
Android s'appuie sur le composant Type Enforcement (TE) de SELinux pour sa politique. Cela signifie que tous les objets (tels que fichier, processus ou socket) ont un type qui leur est associé. Par exemple, par défaut, une application aura le type untrusted_app
. Pour un processus, son type est également appelé son domaine . Il est possible d'annoter un type avec un ou plusieurs attributs . Les attributs sont utiles pour faire référence à plusieurs types en même temps.
Les objets sont mappés sur des classes (par exemple, un fichier, un répertoire, un lien symbolique, un socket) et les différents types d'accès pour chaque classe sont représentés par des permissions . Par exemple, l'autorisation open
existe pour le file
de classe . Alors que les types et les attributs sont régulièrement mis à jour dans le cadre de la politique Android SELinux, les autorisations et les classes sont définies de manière statique et rarement mises à jour dans le cadre d'une nouvelle version de Linux.
Une règle de politique se présente sous la forme : allow source target : class permissions ;
où:
- Source - Le type (ou attribut) du sujet de la règle. Qui demande l'accès ?
- Cible - Le type (ou attribut) de l'objet. A quoi est l'accès demandé ?
- Classe - Le type d'objet (par exemple, fichier, socket) auquel on accède.
- Autorisations - L'opération (ou l'ensemble d'opérations) (par exemple, lecture, écriture) en cours d'exécution.
Un exemple de règle est :
allow untrusted_app app_data_file:file { read write };
Cela indique que les applications sont autorisées à lire et à écrire des fichiers étiquetés app_data_file
. Il existe d'autres types d'applications. Pour les instances, isolated_app
est utilisé pour les services d'application avec isolatedProcess=true
dans leur manifeste. Au lieu de répéter la règle pour les deux types, Android utilise un attribut nommé appdomain
pour tous les types qui couvrent les applications :
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app, appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app, appdomain; allow appdomain app_data_file:file { read write };
Lorsqu'une règle est écrite qui spécifie un nom d'attribut, ce nom est automatiquement étendu à la liste des domaines ou des types associés à l'attribut. Certains attributs notables sont :
-
domain
- attribut associé à tous les types de processus, -
file_type
- attribut associé à tous les types de fichiers.
Macros
Pour l'accès aux fichiers en particulier, il existe de nombreux types d'autorisations à prendre en compte. Par exemple, l'autorisation de read
n'est pas suffisante pour ouvrir le fichier ou appeler stat
dessus. Pour simplifier la définition des règles, Android fournit un ensemble de macros pour gérer les cas les plus courants. Par exemple, afin d'inclure les autorisations manquantes telles que open
, la règle ci-dessus pourrait être réécrite comme suit :
allow appdomain app_data_file:file rw_file_perms;
Voir les fichiers global_macros
et te_macros
pour plus d'exemples de macros utiles. Les macros doivent être utilisées chaque fois que possible pour aider à réduire la probabilité d'échecs dus à des refus d'autorisations associées.
Une fois qu'un type est défini, il doit être associé au fichier ou au processus qu'il représente. Voir Implémentation de SELinux pour plus de détails sur la façon dont cette association est effectuée. Pour plus d'informations sur les règles, consultez le Notebook SELinux .
Contexte et catégories de sécurité
Lors du débogage des politiques SELinux ou des fichiers d'étiquetage (via file_contexts
ou lors de l'exécution de ls -Z
), vous pouvez rencontrer un contexte de sécurité (également appelé label ). Par exemple : u:r:untrusted_app:s0:c15,c256,c513,c768
. Un contexte de sécurité a le format : user:role:type:sensitivity[:categories]
. Vous pouvez généralement ignorer les champs user
, role
et sensitivity
d'un contexte (voir Spécificité ). Le champ type
est expliqué dans la section précédente. categories
partie de la prise en charge de la sécurité multiniveau (MLS) dans SELinux. Depuis Android S, les catégories servent à :
- Isolez les données de l'application de l'accès par une autre application,
- Isolez les données de l'application d'un utilisateur physique à un autre.
Spécificité
Android n'utilise pas toutes les fonctionnalités fournies par SELinux. Lorsque vous lisez de la documentation externe, gardez ces points à l'esprit :
- La majorité des politiques d'AOSP sont définies à l'aide du langage de politique du noyau. Il existe quelques exceptions pour l'utilisation du langage intermédiaire commun (CIL).
- Les utilisateurs SELinux ne sont pas utilisés. Le seul utilisateur défini est
u
. Lorsque nécessaire, les utilisateurs physiques sont représentés à l'aide du champ catégories d'un contexte de sécurité. - Les rôles SELinux et le contrôle d'accès basé sur les rôles (RBAC) ne sont pas utilisés. Deux rôles par défaut sont définis et utilisés :
r
pour les sujets etobject_r
pour les objets. - Les sensibilités SELinux ne sont pas utilisées. La sensibilité
s0
par défaut est toujours définie. - Les booléens SELinux ne sont pas utilisés. Une fois la stratégie créée pour un appareil, elle ne dépend pas de l'état de l'appareil. Cela simplifie l'audit et le débogage des stratégies.