Google s'est engagé à promouvoir l'équité raciale pour les communautés noires. Regarde comment.
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Rédaction de la politique SELinux

Le projet Android Open Source (AOSP) fournit une politique de base solide pour les applications et les services communs à tous les appareils Android. Les contributeurs à l'AOSP affinent régulièrement cette politique. La stratégie de base devrait représenter environ 90 à 95% de la stratégie finale sur l'appareil, les personnalisations spécifiques à l'appareil constituant les 5 à 10% restants. Cet article se concentre sur ces personnalisations spécifiques à l'appareil, sur la façon d'écrire une stratégie spécifique à l'appareil et sur certains des pièges à éviter en cours de route.

Mise en place de l'appareil

Lors de la rédaction d'une stratégie spécifique à l'appareil, procédez comme suit.

Exécuter en mode permissif

Lorsqu'un appareil est en mode permissif , les refus sont consignés mais ne sont pas appliqués. Le mode permissif est important pour deux raisons:

  • Le mode permissif garantit que l'activation de la stratégie ne retarde pas les autres tâches de mise en service précoce de l'appareil.
  • Un refus forcé peut masquer d'autres refus. Par exemple, l'accès aux fichiers implique généralement une recherche dans un répertoire, une ouverture de fichier, puis une lecture de fichier. En mode d'application, seul le refus de recherche dans l'annuaire se produirait. Le mode permissif garantit que tous les refus sont visibles.

Le moyen le plus simple de mettre un périphérique en mode permissif consiste à utiliser la ligne de commande du noyau . Cela peut être ajouté au fichier BoardConfig.mk du BoardConfig.mk : platform/device/<vendor>/<target>/BoardConfig.mk . Après avoir modifié la ligne de commande, effectuez make clean , puis make bootimage une image de démarrage et make bootimage la nouvelle image de démarrage.

Après cela, confirmez le mode permissif avec:

adb shell getenforce

Deux semaines est un délai raisonnable pour être en mode permissif global. Après avoir résolu la majorité des refus, repassez en mode d'application et corrigez les bogues au fur et à mesure qu'ils surviennent. Les domaines qui produisent encore des refus ou les services encore en développement peuvent être temporairement mis en mode permissif, mais les remettre en mode d'application dès que possible.

Appliquer tôt

En mode d'application, les refus sont à la fois consignés et appliqués. Il est recommandé de mettre votre appareil en mode d'application le plus tôt possible. Attendre la création et l'application d'une politique spécifique à l'appareil entraîne souvent un produit bogué et une mauvaise expérience utilisateur. Commencez suffisamment tôt pour participer à la dogfooding et assurez une couverture de test complète des fonctionnalités dans le monde réel. Commencer tôt garantit que les problèmes de sécurité éclairent les décisions de conception. À l'inverse, l'octroi d'autorisations basées uniquement sur les refus observés est une approche peu sûre. Utilisez ce temps pour effectuer un audit de sécurité de l'appareil et signaler les bogues contre les comportements qui ne devraient pas être autorisés.

Supprimer ou supprimer une stratégie existante

Il existe un certain nombre de bonnes raisons de créer une politique spécifique à un appareil à partir de zéro sur un nouvel appareil, notamment:

Résoudre les refus de services de base

Les refus générés par les services de base sont généralement traités par l'étiquetage des fichiers. Par exemple:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

est complètement traité en étiquetant correctement /dev/kgsl-3d0 . Dans cet exemple, tcontext est un device . Cela représente un contexte par défaut où tout dans /dev reçoit l'étiquette « périphérique » à moins qu'une étiquette plus spécifique ne soit attribuée. Le simple fait d'accepter la sortie de audit2allow ici aboutirait à une règle incorrecte et trop permissive.

Pour résoudre ce genre de problème, attribuez au fichier une étiquette plus spécifique, qui dans ce cas est gpu_device . Aucune autorisation supplémentaire n'est nécessaire car le serveur multimédia dispose déjà des autorisations nécessaires dans la stratégie principale pour accéder à gpu_device.

Autres fichiers spécifiques au périphérique qui doivent être étiquetés avec des types prédéfinis dans la stratégie principale:

En général, l'octroi d'autorisations aux étiquettes par défaut est incorrect. Beaucoup de ces autorisations sont interdites par les règles Neverallow , mais même lorsqu'elles ne sont pas explicitement interdites, la meilleure pratique consiste à fournir une étiquette spécifique.

Étiqueter les nouveaux services et traiter les refus

Les services lancés par init doivent s'exécuter dans leurs propres domaines SELinux. L'exemple suivant place le service «foo» dans son propre domaine SELinux et lui accorde des autorisations.

Le service est lancé dans l' init. device .rc notre appareil init. device .rc fichier init. device .rc comme:

service foo /system/bin/foo
    class core
  1. Créer un nouveau domaine "foo"

    Créez le fichier device/ manufacturer / device-name /sepolicy/foo.te avec le contenu suivant:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    Il s'agit du modèle initial du domaine foo SELinux, auquel vous pouvez ajouter des règles basées sur les opérations spécifiques effectuées par cet exécutable.

  2. Étiquette /system/bin/foo

    Ajoutez ce qui suit à device/ manufacturer / device-name /sepolicy/file_contexts :

    /system/bin/foo   u:object_r:foo_exec:s0
    

    Cela garantit que l'exécutable est correctement étiqueté afin que SELinux exécute le service dans le domaine approprié.

  3. Créez et flashez les images de démarrage et système.
  4. Affinez les règles SELinux pour le domaine.

    Utilisez les refus pour déterminer les autorisations requises. L'outil audit2allow fournit de bonnes directives, mais ne l'utilise que pour éclairer la rédaction de politiques. Ne copiez pas simplement la sortie.

Revenir en mode d'application

C'est bien de dépanner en mode permissif, mais revenez en mode d'application le plus tôt possible et essayez de rester là.

Erreurs fréquentes

Voici quelques solutions aux erreurs courantes qui se produisent lors de la rédaction de stratégies spécifiques à un appareil.

Abus de négation

L'exemple de règle suivant revient à verrouiller la porte d'entrée mais à laisser les fenêtres ouvertes:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

L'intention est claire: tout le monde, sauf les applications tierces, peut avoir accès au périphérique de débogage.

La règle est imparfaite de plusieurs manières. L'exclusion de untrusted_app est simple à contourner car toutes les applications peuvent éventuellement exécuter des services dans le domaine isolated_app . De même, si de nouveaux domaines pour des applications tierces sont ajoutés à AOSP, ils auront également accès à scary_debug_device . La règle est trop permissive. La plupart des domaines ne bénéficieront pas de l'accès à cet outil de débogage. La règle doit avoir été écrite pour autoriser uniquement les domaines qui nécessitent un accès.

Fonctionnalités de débogage en production

Les fonctionnalités de débogage ne doivent pas être présentes sur les versions de production, ni leur stratégie.

L'alternative la plus simple est de n'autoriser la fonction de débogage que lorsque SELinux est désactivé sur les versions eng / userdebug, telles que adb root et adb shell setenforce 0 .

Une autre alternative sûre consiste à inclure les autorisations de débogage dans une instruction userdebug_or_eng .

Explosion de la taille des politiques

Caractériser les politiques SEAndroid dans la nature décrit une tendance préoccupante dans la croissance des personnalisations de politique des appareils. La stratégie spécifique au périphérique doit représenter 5 à 10% de la stratégie globale exécutée sur un périphérique. Les personnalisations dans la plage de 20% + contiennent presque certainement des domaines privilégiés et une politique morte.

Politique inutilement volumineuse:

  • Prend un double coup sur la mémoire car la stratégie se trouve dans le disque RAM et est également chargée dans la mémoire du noyau.
  • Gâche de l'espace disque en nécessitant une image de démarrage plus grande.
  • Affecte les heures de recherche des règles d'exécution.

L'exemple suivant montre deux appareils pour lesquels la politique spécifique au fabricant représentait 50% et 40% de la politique sur l'appareil. Une réécriture de la politique a apporté des améliorations de sécurité substantielles sans perte de fonctionnalité, comme indiqué ci-dessous. (Les appareils AOSP Shamu et Flounder sont inclus à des fins de comparaison.)

Figure 1: Comparaison de la taille de la politique spécifique à l'appareil après un audit de sécurité.

Graphique 1 . Comparaison de la taille de la politique spécifique à l'appareil après un audit de sécurité.

Dans les deux cas, la stratégie a été considérablement réduite à la fois en taille et en nombre d'autorisations. La diminution de la taille de la politique est presque entièrement due à la suppression des autorisations inutiles, dont beaucoup étaient probablement des règles générées par audit2allow qui ont été ajoutées sans discernement à la politique. Les domaines morts étaient également un problème pour les deux appareils.

Octroi de la capacité dac_override

Un refus dac_override signifie que le processus incriminé tente d'accéder à un fichier avec les autorisations utilisateur / groupe / monde Unix incorrectes. La bonne solution est presque de ne jamais accorder la permission dac_override . Modifiez plutôt les autorisations Unix sur le fichier ou le processus . Quelques domaines tels que init , vold et installd vraiment besoin de la possibilité de remplacer les autorisations de fichiers Unix pour accéder aux fichiers d'autres processus. Voir le blog de Dan Walsh pour une explication plus approfondie.