Concepts SELinux

Consultez cette page pour vous familiariser avec les concepts 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 le propriétaire d'une ressource particulière contrôle les autorisations d'accès qui lui sont associées. Il s'agit généralement d'une approche grossière et sujette à une élévation involontaire des privilèges. Toutefois, un système MAC consulte une autorité centrale pour prendre une décision sur toutes les tentatives d'accès.

SELinux a été implémenté dans le framework Linux Security Module (LSM), qui reconnaît divers objets de kernel et les actions sensibles qui y sont effectuées. Au moment où chacune de ces actions doit être effectuée, une fonction de crochet LSM est appelée pour déterminer si l'action doit être autorisée ou non en fonction des informations qui y sont stockées dans un objet de sécurité opaque. SELinux fournit une implémentation de ces hooks et la gestion de ces objets de sécurité, qui se combinent avec sa propre stratégie pour déterminer les décisions d'accès.

Avec d'autres mesures de sécurité Android, la règle de contrôle des 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 permet de structurer votre logiciel pour vous assurer qu'il ne s'exécute qu'au niveau d'autorisation minimal. Cela atténue les effets des attaques et réduit la probabilité que des processus erronés écrasent ou même transmettent des données.

Sous Android 4.3 et versions ultérieures, SELinux fournit un contrôle d'accès obligatoire (MAC) couvrant les environnements de contrôle d'accès discrétionnaire (DAC) traditionnels. Par exemple, les logiciels doivent généralement s'exécuter en tant que compte utilisateur racine pour écrire sur des appareils de bloc bruts. Dans un environnement Linux basé sur le DAC traditionnel, si l'utilisateur racine est compromis, il peut écrire sur tous les appareils de bloc brut. Toutefois, SELinux peut être utilisé pour étiqueter ces appareils afin que le processus auquel est attribué l'accès root ne puisse écrire que sur ceux spécifiés dans la règle associée. De cette manière, le processus ne peut pas écraser les données et les paramètres système en dehors de l'appareil de bloc brut spécifique.

Pour obtenir d'autres exemples de menaces et de solutions à ces menaces avec SELinux, consultez la section Cas d'utilisation.

Niveaux d'application

SELinux peut être implémenté dans différents modes:

  • Permissive (Permissive) : les règles de sécurité SELinux ne sont pas appliquées, mais consignées.
  • Application : la stratégie de sécurité est appliquée et enregistrée. Les échecs s'affichent sous la forme d'erreurs EPERM.

Ce choix est binaire et détermine si votre règle prend des mesures ou vous permet simplement de collecter des échecs potentiels. L'approche permissive est particulièrement utile lors de l'implémentation.

Types, attributs et règles

Android s'appuie sur le composant d'application des types (TE) de SELinux pour sa stratégie. Cela signifie que tous les objets (fichier, processus ou socket, par exemple) sont associés à un type. Par exemple, par défaut, une application est de type untrusted_app. Pour un processus, son type est également appelé son domaine. Vous pouvez 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 autorisations. Par exemple, l'autorisation open existe pour la classe file. Bien que les types et les attributs soient régulièrement mis à jour dans le cadre de la stratégie SELinux Android, 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 stratégie se présente sous la forme suivante : allow source target:class permissions; où:

  • Source : type (ou attribut) du sujet de la règle. Qui demande l'accès ?
  • Cible : type (ou attribut) de l'objet. À quoi l'accès est-il demandé ?
  • Classe : type d'objet (par exemple, fichier, socket) auquel on accède.
  • Autorisations : opération (ou ensemble d'opérations) (par exemple, lecture, écriture) en cours d'exécution.

Voici un exemple de règle:

allow untrusted_app app_data_file:file { read write };

Cela signifie que les applications sont autorisées à lire et à écrire des fichiers marqués comme app_data_file. Il existe d'autres types d'applications. Par exemple, isolated_app est utilisé pour les services d'application avec isolatedProcess=true dans leur fichier manifeste. Au lieu de répéter la règle pour les deux types, Android utilise un attribut nommé appdomain pour tous les types couvrant 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 spécifiant un nom d'attribut est écrite, ce nom est automatiquement étendu à la liste des domaines ou types associés à l'attribut. Voici quelques-uns des attributs les plus importants:

  • 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, de nombreux types d'autorisations doivent être pris en compte. Par exemple, l'autorisation read n'est pas suffisante pour ouvrir le fichier ni pour 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, pour inclure les autorisations manquantes telles que open, la règle ci-dessus peut être réécrite comme suit:

allow appdomain app_data_file:file rw_file_perms;

Consultez les fichiers global_macros et te_macros pour obtenir d'autres exemples de macros utiles. Dans la mesure du possible, utilisez des macros pour réduire la probabilité de défaillances dues à 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. Pour en savoir plus sur cette association, consultez la section Implémenter SELinux. Pour en savoir plus sur les règles, consultez le notebook SELinux.

Contexte et catégories de sécurité

Lorsque vous déboguez des stratégies SELinux ou des fichiers d'étiquetage (à l'aide de file_contexts ou lorsque vous exécutez ls -Z), vous pouvez rencontrer un contexte de sécurité (également appelé libellé). Par exemple : u:r:untrusted_app:s0:c15,c256,c513,c768. Un contexte de sécurité se présente sous la forme suivante : 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 fait partie de la prise en charge de la sécurité multiniveau (MLS) dans SELinux. Dans Android 12 et versions ultérieures, les catégories servent à:

  • Isoler les données de l'application de l'accès d'une autre application ;
  • Isoler 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, tenez compte des points suivants:

  • La plupart des règles d'AOSP sont définies à l'aide du Kernel Policy Language. Il existe quelques exceptions pour l'utilisation du langage CIL (Common Intermediate Language).
  • Les utilisateurs SELinux ne sont pas utilisés. Le seul utilisateur défini est u. Si nécessaire, les utilisateurs physiques sont représentés à l'aide du champ "categories" d'un contexte de sécurité.
  • Les rôles SELinux et le contrôle des 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 et object_r pour les objets.
  • Les sensibilités SELinux ne sont pas utilisées. La sensibilité par défaut de s0 est toujours définie.
  • Les valeurs booléennes SELinux ne sont pas utilisées. Lorsque la règle est créée pour un appareil, elle ne dépend pas de son état. Cela simplifie l'audit et le débogage des règles.