Élaboration 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 principale (plate-forme) et de la politique spécifique à l'appareil (fournisseur). Le flux de construction de politique SELinux pour Android 4.4 à Android 7.0 a fusionné tous les fragments sepolicy, puis a 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 politique de plate-forme et de fournisseur est créée 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 plate-forme.

Cependant, comme les fichiers de politique 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 qu'il puisse lire les fichiers SELinux 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 libselinux externe 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/partagée hôte, bibliothèque statique cible).
    • external/selinux/checkpolicy : compilateur de politiques SELinux (exécutables hôtes : checkpolicy , checkmodule et dispol ). Dépend de libsepol .
  • system/sepolicy : configurations de politique Core Android SELinux, y compris les contextes et les fichiers de politique. La logique de construction majeure de sepolicy est également ici ( system/sepolicy/Android.mk ).

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

Android 7.0 et versions antérieures

Cette section explique comment la politique SELinux est construite dans Android 7.x et versions antérieures.

Élaboration 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 politique et à divers vérificateurs. La personnalisation spécifique à l'appareil est effectuée via la variable BOARD_SEPOLICY_DIRS définie dans le fichier Boardconfig.mk spécifique à l'appareil. 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 à l'appareil, afin de générer les configurations SELinux finales pour un appareil 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 texte brut policy.conf est généré en concaténant security_classes , initial_sids , fichiers *.te genfs_contexts et port_contexts dans cet ordre.
  • Pour chaque fichier (comme security_classes ), son contenu est la concaténation des fichiers portant le 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 liés à SELinux suivants :

  • 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 de SELinux

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

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

Pour raccourcir le temps de démarrage, exécutez le re-exec() sur le processus d' 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 de la politique de plate-forme/fournisseur tout en maintenant la compatibilité.

La sepolicy de plate-forme est en outre divisée en parties privées de plate-forme et parties publiques de plate-forme pour exporter des types et des attributs spécifiques vers les rédacteurs de politique du fournisseur. Les types/attributs publics de la plate-forme sont garantis pour être maintenus en tant qu'API stables pour une version de plate-forme donnée. La compatibilité avec les types/attributs publics de plate-forme précédents peut être garantie pour plusieurs versions à l'aide de fichiers de mappage de plate-forme.

Plateforme publique sepolicy

La plate-forme public sepolicy inclut tout ce qui est défini sous system/sepolicy/public . La plate-forme peut supposer que les types et attributs définis dans le cadre de la politique publique sont des API stables pour une version de plate-forme donnée. Il s'agit de la partie de la sepolicy qui est exportée par la plate-forme sur laquelle les développeurs de politiques du fournisseur (c'est-à-dire de l'appareil) peuvent écrire une politique supplémentaire spécifique à l'appareil.

Les types sont versionnés en fonction de la version de la politique 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 d'origine) dans la politique de la plate-forme. Ainsi, la politique finale comprend la politique de plate-forme privée, la politique de sécurité publique de la plate-forme actuelle, la politique spécifique à l'appareil et la politique publique versionnée correspondant à la version de la plate-forme sur laquelle la politique de l'appareil a été écrite.

Politique privée de la plate-forme

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

Cartographie privée de la plateforme

Le mappage privé de la plate-forme inclut des déclarations de stratégie qui mappent les attributs exposés dans la politique publique de la plate-forme des versions précédentes de la plate-forme aux types concrets utilisés dans la stratégie publique de la plate-forme actuelle. Cela garantit que la politique du fournisseur qui a été écrite sur la base des attributs publics de la plate-forme de la ou des versions précédentes de la politique publique de la plate-forme 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 plateforme donnée. Un fichier de mappage distinct existe pour chaque version de plate-forme précédente à partir de laquelle cette plate-forme est censée accepter la politique du fournisseur. Pour plus de détails, voir Compatibilité .

Android 11 et supérieur

system_ext et sepolicy du produit

Dans Android 11, la politique system_ext et la politique produit sont ajoutées. Comme la sepolicy de plate-forme, la politique system_ext et la politique de 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 dans 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 chaque partition system_ext et produit.

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

system_ext et mappage de produit

system_ext et product sont autorisés à exporter leurs types publics désignés vers le fournisseur. Cependant, la responsabilité de maintenir 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 de confidentialité 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.

    Élaboration d'une politique SELinux

    La politique SELinux dans Android 8.0 est faite en combinant des éléments de /system et /vendor . La logique de configuration appropriée se trouve dans /platform/system/sepolicy/Android.mk .

    La politique existe dans les emplacements suivants :

    Emplacement Contient
    system/sepolicy/public L'API sepolicy de la plateforme
    system/sepolicy/private Détails de mise en œuvre de la plate-forme (les fournisseurs peuvent ignorer)
    system/sepolicy/vendor Fichiers de politique 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 confidentialité d'ODM
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 et supérieur) API sepolicy de System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 et supérieur) Détails de mise en œuvre de System_ext (les fournisseurs peuvent ignorer)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 et versions ultérieures) API sepolicy 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 construction prend cette politique et produit des composants de politique système, system_ext, product, vendor 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 plate-forme publique (système + système_ext + produit)
      2. politique combinée privée + publique
      3. public + fournisseur et politique BOARD_SEPOLICY_DIRS
    2. Gestion des versions de la politique fournie par le public dans le cadre de la politique du fournisseur. Effectué en utilisant la politique CIL publique produite pour informer la politique combinée publique + fournisseur + BOARD_SEPOLICY_DIRS quant aux parties qui doivent être transformées en attributs qui seront liés à la politique de la plate-forme.
    3. Création d'un fichier de mapping liant les parties plateforme et vendeur. Initialement, cela relie simplement les types de la politique publique aux attributs correspondants dans la politique du fournisseur ; plus tard, il fournira également la base du fichier maintenu dans les futures versions de la plate-forme, permettant la compatibilité avec la politique du fournisseur ciblant cette version de la plate-forme.
    4. Combinaison de fichiers de stratégie (décrire à la fois les solutions sur l'appareil et les solutions 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 qu'init init init tous les fichiers CIL des partitions ( system , system_ext , product , vendor et odm ) et les compile en 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 precompiled_sepolicy ou /odm/etc/selinux/precompiled_sepolicy , avec les hachages sha256 des fichiers CIL d'entrée. Lors de l'exécution, init vérifie si l'un des fichiers de politique 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, la stratégie précompilée est utilisée si toutes les conditions suivantes sont remplies. Ici, {partition} représente la partition où la politique précompilée existe : 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.