Création d'une politique SELinux

Cet article explique comment la politique SELinux est construite. La politique SELinux est construite à partir de la combinaison de la politique AOSP de base (plate-forme) et de la politique spécifique au périphérique (fournisseur). Le flux de création de stratégie SELinux pour Android 4.4 à Android 7.0 a fusionné tous les fragments de stratégie, puis généré des fichiers monolithiques dans le répertoire racine. Cela signifiait que les fournisseurs de SoC et les fabricants d'ODM modifiaient boot.img (pour les appareils non-A/B) ou system.img (pour les appareils A/B) chaque fois que la politique était modifiée.

Dans Android 8.0 et versions ultérieures, la stratégie de plate-forme et celle du fournisseur sont créées séparément. Les SOC et les OEM peuvent mettre à jour leurs parties de la politique, créer leurs images (telles que vendor.img et boot.img ), puis mettre à jour ces images indépendamment des mises à jour de la plateforme.

Cependant, comme les fichiers de stratégie SELinux modularisés sont stockés sur les partitions /vendor , le processus init doit monter les partitions système et fournisseur plus tôt afin de pouvoir lire les fichiers SELinux à partir de ces partitions et les fusionner avec les fichiers SELinux principaux dans le répertoire système (avant de les charger dans le noyau).

Fichiers source

La logique de construction de SELinux se trouve dans ces fichiers :

  • external/selinux : projet SELinux externe, utilisé pour créer des utilitaires de ligne de commande HOST pour compiler la politique et les étiquettes SELinux.
    • external/selinux/libselinux : Android utilise uniquement un sous-ensemble du projet externe libselinux ainsi que certaines personnalisations spécifiques à Android. Pour plus de détails, voir external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : Détermine si un contexte de sécurité est valide pour une politique binaire donnée (exécutable hôte).
      • libsepol : bibliothèque SELinux pour manipuler les politiques de sécurité binaires (bibliothèque statique hôte/partagée, bibliothèque statique cible).
    • external/selinux/checkpolicy : compilateur de politiques SELinux (exécutables hôtes : checkpolicy , checkmodule et dispol ). Cela dépend de libsepol .
  • system/sepolicy : configurations de stratégie de base d'Android SELinux, y compris les contextes et les fichiers de stratégie. La logique majeure de construction de la politique de sécurité est également ici ( system/sepolicy/Android.mk ).

Pour plus de détails sur les fichiers dans system/sepolicy Implémentation de SELinux .

Android 7.0 et versions antérieures

Cette section explique comment la stratégie SELinux est créée dans Android 7.x et versions antérieures.

Création d'une politique SELinux

La politique SELinux est créée en combinant la politique AOSP principale avec des personnalisations spécifiques à l'appareil. La politique combinée est ensuite transmise au compilateur de politiques et à divers vérificateurs. La personnalisation spécifique au périphérique est effectuée via la variable BOARD_SEPOLICY_DIRS définie dans le fichier Boardconfig.mk spécifique au périphérique. Cette variable de construction globale contient une liste de répertoires qui spécifient l'ordre dans lequel rechercher des fichiers de stratégie supplémentaires.

Par exemple, un fournisseur de SoC et un ODM peuvent chacun ajouter un répertoire, un pour les paramètres spécifiques au SoC et un autre pour les paramètres spécifiques au périphérique, afin de générer les configurations SELinux finales pour un périphérique donné :

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

Le contenu des fichiers file_contexts dans system/sepolicy et BOARD_SEPOLICY_DIRS sont concaténés pour générer le file_contexts.bin sur l'appareil :

Cette image montre la logique de construction SELinux pour Android 7.x.
Figure 1 . Logique de construction SELinux

Le fichier sepolicy se compose de plusieurs fichiers sources :

  • Le policy.conf en texte brut est généré en concaténant les fichiers security_classes , initial_sids , *.te , genfs_contexts et port_contexts dans cet ordre.
  • Pour chaque fichier (comme security_classes ), son contenu est la concaténation des fichiers du même nom sous system/sepolicy/ et BOARDS_SEPOLICY_DIRS .
  • Le policy.conf est envoyé au compilateur SELinux pour vérification de la syntaxe et compilé au format binaire en tant que sepolicy sur l'appareil.
    Cette image montre les fichiers qui génèrent le fichier de stratégie SELinux pour Android 7.x.
    Figure 2 . Fichier de stratégie SELinux

Fichiers SELinux

Après la compilation, les appareils Android exécutant 7.x et versions antérieures contiennent généralement les fichiers suivants liés à SELinux :

  • selinux_version
  • sepolicy : sortie binaire après combinaison des fichiers de stratégie (tels que security_classes , initial_sids et *.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Pour plus de détails, consultez Implémentation de SELinux .

Initialisation SELinux

Lorsque le système démarre, SELinux est en mode permissif (et non en mode d'application). Le processus d'initialisation effectue les tâches suivantes :

  • Charge les fichiers sepolicy du disque virtuel dans le noyau via /sys/fs/selinux/load .
  • Fait passer SELinux en mode d'application.
  • Exécute re-exec() pour appliquer la règle de domaine SELinux à lui-même.

Pour raccourcir le temps de démarrage, effectuez la re-exec() sur le processus init dès que possible.

Android 8.0 et supérieur

Dans Android 8.0, la politique SELinux est divisée en composants de plate-forme et de fournisseur pour permettre des mises à jour indépendantes des politiques de plate-forme/fournisseur tout en maintenant la compatibilité.

La stratégie de plate-forme est en outre divisée en parties privées et publiques de plate-forme pour exporter des types et des attributs spécifiques aux rédacteurs de politiques des fournisseurs. Il est garanti que les types/attributs publics de la plateforme seront conservés en tant qu'API stables pour une version de plateforme donnée. La compatibilité avec les types/attributs publics de plateforme précédents peut être garantie pour plusieurs versions à l'aide de fichiers de mappage de plateforme.

Politique publique de la plateforme

La politique publique de la plateforme comprend tout ce qui est défini sous system/sepolicy/public . La plateforme peut supposer que les types et attributs définis dans le cadre de la politique publique sont des API stables pour une version donnée de la plateforme. Cela fait partie de la stratégie exportée par plate-forme sur laquelle les développeurs de politiques de fournisseur (c'est-à-dire de périphérique) peuvent écrire une politique supplémentaire spécifique au périphérique.

Les types sont versionnés en fonction de la version de la stratégie sur laquelle les fichiers du fournisseur sont écrits, définie par la variable de construction PLATFORM_SEPOLICY_VERSION . La politique publique versionnée est ensuite incluse dans la politique du fournisseur et (sous sa forme originale) dans la politique de la plateforme. Ainsi, la politique finale comprend la politique de plate-forme privée, la politique publique de la plate-forme actuelle, la politique spécifique au périphérique et la politique publique versionnée correspondant à la version de la plate-forme par rapport à laquelle la politique du périphérique a été écrite.

Séparation privée de la plateforme

La politique de sécurité privée de la plateforme inclut tout ce qui est défini sous /system/sepolicy/private . Cette partie de la stratégie forme uniquement les types, autorisations et attributs requis pour la fonctionnalité de la plateforme. Celles-ci ne sont pas exportées vers les rédacteurs de stratégies vendor/device . Les rédacteurs de politiques hors plateforme ne doivent pas écrire leurs extensions de stratégie en fonction des types/attributs/règles définis dans la stratégie privée de la plateforme. De plus, ces règles peuvent être modifiées ou peuvent disparaître dans le cadre d'une mise à jour du framework uniquement.

Cartographie privée de la plateforme

Le mappage privé de plateforme comprend des déclarations de politique qui mappent les attributs exposés dans la politique publique de plateforme des versions précédentes de plateforme aux types concrets utilisés dans la politique publique actuelle de plateforme. Cela garantit que la stratégie du fournisseur qui a été rédigée sur la base des attributs publics de la plateforme des versions précédentes de la stratégie publique de la plateforme continue de fonctionner. La gestion des versions est basée sur la variable de construction PLATFORM_SEPOLICY_VERSION définie dans AOSP pour une version de plate-forme donnée. Un fichier de mappage distinct existe pour chaque version précédente de la plateforme à partir de laquelle cette plateforme est censée accepter la politique du fournisseur. Pour plus de détails, voir Compatibilité .

Android 11 et supérieur

system_ext et la politique du produit

Dans Android 11, la stratégie system_ext et la stratégie produit sont ajoutées. Comme la politique de plate-forme, la politique system_ext et la politique produit sont divisées en politique publique et politique privée.

La politique publique est exportée vers le fournisseur. Les types et les attributs deviennent une API stable et la politique du fournisseur peut faire référence aux types et aux attributs de la politique publique. Les types sont versionnés selon PLATFORM_SEPOLICY_VERSION , et la stratégie versionnée est incluse dans la stratégie du fournisseur. La stratégie d'origine est incluse dans chacune des partitions system_ext et product.

La stratégie privée contient les types, autorisations et attributs system_ext uniquement et produits uniquement requis pour la fonctionnalité system_ext et les partitions de produit. La politique privée est invisible pour le fournisseur, ce qui implique que ces règles sont internes et peuvent être modifiées.

system_ext et cartographie des produits

system_ext et product sont autorisés à exporter leurs types publics désignés vers le fournisseur. Cependant, la responsabilité du maintien de la compatibilité incombe à chaque partenaire. Pour des raisons de compatibilité, les partenaires peuvent fournir leurs propres fichiers de mappage qui mappent les attributs versionnés des versions précédentes aux types concrets utilisés dans la politique publique actuelle.

  • Pour installer un fichier de mappage pour system_ext, placez un fichier cil contenant les informations de mappage souhaitées dans {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , puis ajoutez system_ext_{ver}.cil à PRODUCT_PACKAGES .
  • Pour installer un fichier de mappage pour le produit, placez un fichier cil contenant les informations de mappage souhaitées dans {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , puis ajoutez product_{ver}.cil à PRODUCT_PACKAGES .
  • Reportez-vous à un exemple qui ajoute un fichier de mappage de la partition produit du périphérique Redbull.

    Création d'une politique SELinux

    La politique SELinux dans Android 8.0 est élaborée en combinant des éléments de /system et /vendor . La logique pour configurer cela de manière appropriée se trouve dans /platform/system/sepolicy/Android.mk .

    La stratégie existe aux emplacements suivants :

    Emplacement Contient
    system/sepolicy/public L'API de politique de la plateforme
    system/sepolicy/private Détails de mise en œuvre de la plateforme (les fournisseurs peuvent ignorer)
    system/sepolicy/vendor Fichiers de stratégie et de contexte que les fournisseurs peuvent utiliser (les fournisseurs peuvent ignorer s'ils le souhaitent)
    BOARD_SEPOLICY_DIRS Politique de confidentialité du fournisseur
    BOARD_ODM_SEPOLICY_DIRS (Android 9 et supérieur) Politique de sécurité Odm
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 et supérieur) API de politique de sécurité de System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 et supérieur) Détails de l'implémentation de System_ext (les fournisseurs peuvent ignorer)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 et versions ultérieures) API de politique de sécurité du produit
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 et versions ultérieures) Détails de mise en œuvre du produit (les fournisseurs peuvent ignorer)

    Le système de build prend cette stratégie et produit les composants de stratégie système, system_ext, produit, fournisseur et odm sur la partition correspondante. Les étapes comprennent :

    1. Conversion des politiques au format SELinux Common Intermediate Language (CIL), en particulier :
      1. politique de plateforme publique (système + system_ext + produit)
      2. politique combinée privée + publique
      3. politique publique + fournisseur et BOARD_SEPOLICY_DIRS
    2. Versionnement de la politique fournie par le public dans le cadre de la politique du fournisseur. Effectué en utilisant la politique publique CIL produite pour informer la politique combinée public + fournisseur + BOARD_SEPOLICY_DIRS quant aux parties qui doivent être transformées en attributs qui seront liés à la politique de plate-forme.
    3. Création d'un fichier de mappage reliant les parties plateforme et fournisseur. Initialement, cela relie simplement les types de la politique publique aux attributs correspondants dans la politique du fournisseur ; plus tard, il servira également de base au fichier conservé dans les futures versions de la plateforme, permettant ainsi la compatibilité avec la politique du fournisseur ciblant cette version de la plateforme.
    4. Combinaison de fichiers de stratégie (décrire les solutions sur appareil et précompilées).
      1. Combinez la cartographie, la plate-forme et la politique des fournisseurs.
      2. Compilez le fichier de stratégie binaire de sortie.

    Politique SELinux précompilée

    Avant que init n'active SELinux, init rassemble tous les fichiers CIL des partitions ( system , system_ext , product , vendor et odm ) et les compile dans une politique binaire, le format qui peut être chargé dans le noyau. Comme la compilation prend du temps (généralement 1 à 2 secondes), les fichiers CIL sont précompilés au moment de la construction et placés dans /vendor/etc/selinux/precompiled_sepolicy ou /odm/etc/selinux/precompiled_sepolicy , avec les hachages sha256. des fichiers CIL d’entrée. Au moment de l'exécution, init vérifie si l'un des fichiers de stratégie a été mis à jour en comparant les hachages. Si rien n'a changé, init charge la politique précompilée. Sinon, init compile à la volée et l'utilise à la place de celui précompilé.

    Plus précisément, une stratégie précompilée est utilisée si toutes les conditions suivantes sont remplies. Ici, {partition} représente la partition où existe la stratégie précompilée : soit vendor , soit odm .

    • /system/etc/selinux/plat_sepolicy_and_mapping.sha256 et /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 existent et sont identiques.
    • /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 et /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 n'existent pas. Ou les deux existent et sont identiques.
    • /product/etc/selinux/product_sepolicy_and_mapping.sha256 et /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 n'existent pas. Ou les deux existent et sont identiques.

    Si l'un d'entre eux diffère, init revient au chemin de compilation sur l'appareil. Voir system/core/init/selinux.cpp pour plus de détails.