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, il existe un concept de propriété selon lequel le 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. Cependant, 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 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 hook LSM est appelée pour déterminer si l'action doit ou non être autorisée en fonction des informations la concernant stockées dans un objet de sécurité opaque. SELinux fournit une implémentation de ces hooks et une gestion de ces objets de sécurité, qui se combinent avec sa propre politique, pour déterminer les décisions d'accès.

Parallèlement à d'autres mesures de sécurité Android, la politique de contrôle d'accès d'Android limite considérablement les dommages potentiels causés aux machines et aux comptes compromis. L'utilisation d'outils tels que les contrôles d'accès discrétionnaires et obligatoires d'Android vous offre une structure permettant de garantir que votre logiciel fonctionne uniquement 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 contrôle d'accès obligatoire (MAC) par rapport aux 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 brut. Dans un environnement Linux traditionnel basé sur DAC, si l'utilisateur root est compromis, il 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 est attribué le privilège root puisse écrire uniquement sur ceux spécifiés dans la politique 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 d'y remédier 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, elle est uniquement enregistrée.
  • Application : la politique de sécurité est appliquée et enregistrée. Les échecs apparaissent sous forme d'erreurs EPERM.

Ce choix est binaire et détermine si votre politique prend des mesures ou vous permet simplement de rassembler les échecs potentiels. Le permissif 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) sont associés à un type . 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 à 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 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 l'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 l'accès est effectué.
  • 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. Par exemple, 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 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 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.

Macro

Pour l’accès aux fichiers en particulier, il existe de nombreux types d’autorisations à prendre en compte. Par exemple, l'autorisation read n'est pas suffisante pour ouvrir le fichier ou appeler stat dessus. Pour simplifier la définition des règles, Android propose un ensemble de macros permettant de 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 autant que possible pour contribuer à réduire le risque 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 SELinux Notebook .

Contexte et catégories de sécurité

Lors du débogage des politiques SELinux ou de l'étiquetage des fichiers (via file_contexts ou lors de l'utilisation 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 font partie de la prise en charge de la sécurité multi-niveaux (MLS) dans SELinux. Depuis Android S, les catégories permettent de :

  • Isoler 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 Kernel Policy Language. 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 cela est 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 et object_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.