Le projet Android Open Source (AOSP) fournit une stratégie de base solide pour le applications et services communs à tous les appareils Android. Les contributeurs d'AOSP affinent régulièrement ce règlement. La stratégie de base est attendue représente environ 90 à 95% de la règle finale sur l'appareil, personnalisées, soit les 5 à 10 % restants. Cet article se concentre sur ces personnalisations propres à l'appareil, comment écrire une stratégie spécifique certains des pièges à éviter en cours de route.
Affichage de l'appareil
Pour rédiger une règle spécifique à un appareil, procédez comme suit :
Exécuter en mode permissif
Lorsqu'un appareil est connecté mode permissif, les refus sont consignés, mais pas appliquées. Le mode permissif est important raisons:
- Le mode permissif permet de s'assurer que la modification des règles ne retarde pas les autres de récupération de l'appareil.
- Un refus forcé peut masquer d'autres refus. Par exemple, l'accès aux fichiers implique généralement une recherche de répertoire, l'ouverture d'un fichier, puis la lecture d'un fichier. Dans seul le refus de la recherche de répertoire se produira. Permissif permet de s'assurer que tous les refus sont visibles.
Le moyen le plus simple de passer un appareil en mode permissif est d'utiliser le
commande kernel
ligne. Cet élément peut être ajouté au fichier BoardConfig.mk
de l'appareil:
platform/device/<vendor>/<target>/BoardConfig.mk
Après avoir modifié la ligne de commande, exécutez make clean
, puis
make bootimage
, puis flashez la nouvelle image de démarrage.
Confirmez ensuite le mode permissif avec:
adb shell getenforce
Une période de deux semaines est un délai raisonnable pour être en mode permissif global. Une fois que vous avez résolu la majorité des refus, repassez à l'étape d'application corriger les insectes dès leur apparition. Les domaines continuent à générer des refus ou à fournir des services en développement intensif peut être temporairement mis en mode permissif, mais déplacer au mode application forcée dès que possible.
Appliquer tôt
En mode "Enforcing", les refus sont à la fois consignés et appliqués. Il est préférable afin de mettre votre appareil en mode application forcée le plus tôt possible. En attente de créer et appliquer des règles spécifiques à l'appareil entraîne souvent des bugs et une mauvaise expérience utilisateur. Commencez suffisamment tôt pour participer à version dogfood et garantir une couverture de test complète des fonctionnalités dans des cas d'utilisation réels. Démarrage... plus tôt permet de s'assurer que les préoccupations de sécurité éclairent les décisions de conception. À l'inverse, le fait d'accorder les autorisations basées uniquement sur les refus observés est une approche risquée. Utiliser ceci de temps pour réaliser un audit de sécurité de l'appareil et signaler les bugs liés aux comportements qui ne devraient pas être autorisés.
Supprimer ou supprimer une règle existante
Il existe un certain nombre de bonnes raisons de créer une règle spécifique à l'appareil à partir de sur un nouvel appareil, y compris:
- Audit de sécurité
- Règle trop permissive
- Réduction de la taille des règles
- Règles en cas de non-respect des règles
Gérer les refus de services principaux
Les refus générés par les services principaux sont généralement traités par l'ajout de libellés aux fichiers. 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 résolu en étiquetant /dev/kgsl-3d0
correctement. Dans
Dans cet exemple, tcontext
est device
. Cela représente
contexte par défaut où tout ce qui se trouve dans /dev
reçoit le
"
appareil", sauf si un libellé plus spécifique lui est attribué. Accepter simplement
la sortie de
audit2allow
entraînerait une règle incorrecte
et trop permissive.
Pour résoudre ce type de problème, attribuez au fichier un libellé plus spécifique, qui dans ce cas est <ph type="x-smartling-placeholder"></ph> gpu_device. Aucune autre autorisation n'est nécessaire, car <ph type="x-smartling-placeholder"></ph> Mediaserver dispose déjà des autorisations nécessaires dans la stratégie de base pour accéder gpu_device.
Les autres fichiers spécifiques à l'appareil qui doivent être libellés avec des types prédéfinis dans règlement principal:
- <ph type="x-smartling-placeholder"></ph> appareils de stockage en mode bloc
- <ph type="x-smartling-placeholder"></ph> appareils audio
- <ph type="x-smartling-placeholder"></ph> appareils vidéo
- <ph type="x-smartling-placeholder"></ph> capteurs
- <ph type="x-smartling-placeholder"></ph> NFC
- appareil_gps
- <ph type="x-smartling-placeholder"></ph> fichiers dans /sys
- fichiers dans /proc
En général, l'attribution d'autorisations aux étiquettes par défaut est incorrecte. Nombre d'entre elles autorisations ne sont pas autorisées par neverallow, mais même s'ils ne sont pas explicitement interdits, il est recommandé de fournir un libellé.
Ajouter un libellé aux nouveaux services et aux nouvelles adresses refus
Les services lancés au démarrage doivent s'exécuter dans leurs propres domaines SELinux. La L'exemple suivant place le service "foo" dans son propre domaine SELinux et lui accorde autorisations.
Le service est lancé dans le
init.device.rc
en tant que:
service foo /system/bin/foo class core
- Créer le domaine "foo"
Créer 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 SELinux "foo", sur lequel vous pouvez ajouter des règles basées sur les opérations spécifiques effectuées par cet exécutable.
- Libellé :
/system/bin/foo
Ajoutez le code suivant à
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 dans le domaine approprié.
- Créez et flashez les images de démarrage et système.
- Affinez les règles SELinux du domaine.
Utilisez les refus pour déterminer les autorisations requises. La audit2allow fournit de bonnes lignes directrices, mais ne les utilisez que pour élaborer des stratégies l'écriture. Ne vous contentez pas de copier le résultat.
Revenir au mode d'application forcée
Vous pouvez résoudre les problèmes en mode permissif, mais recommencez à appliquer le plus tôt possible et essayez d'y rester.
Erreurs courantes
Voici quelques solutions aux erreurs courantes qui se produisent lors de la rédaction règles spécifiques à chaque appareil.
Utilisation excessive de la négation
L'exemple de règle suivant revient à verrouiller la porte d'entrée 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 débogage appareil.
La règle présente des défauts pour plusieurs raisons. L'exclusion de untrusted_app
est simple à contourner, car toutes les applications peuvent éventuellement exécuter des services dans
isolated_app
. De même, si de nouveaux domaines d'applications tierces
sont ajoutés à AOSP, ils auront également accès à scary_debug_device
.
La règle est trop permissive. Pour la plupart des domaines,
l'accès à cet outil de débogage. La règle aurait dû être écrite pour n'autoriser
les domaines nécessitant un accès.
Fonctionnalités de débogage en production
Les fonctionnalités de débogage ne doivent pas être présentes sur les builds de production, .
L'alternative la plus simple consiste à n'autoriser la fonctionnalité 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 solution sûre consiste à placer les autorisations de débogage dans <ph type="x-smartling-placeholder"></ph> userdebug_or_eng.
Évolutivité de la taille de la règle
Caractériser les règles SEAndroid à l'état sauvage décrit une tendance préoccupante concernant la croissance de la personnalisation des règles relatives aux appareils. Les règles spécifiques à l'appareil devraient représenter 5 à 10% de l'ensemble des règles exécutées sur un appareil. Les personnalisations de plus de 20%contiennent presque certainement plus de les domaines privilégiés et les règles mortes.
Règle inutilement volumineuse:
- Prend un double appel sur la mémoire lorsque la stratégie se trouve dans le ramdisk également chargé dans la mémoire du noyau.
- Elle gaspille de l'espace disque en nécessitant une image de démarrage plus grande.
- Affecte les temps de recherche des règles d'exécution.
L'exemple suivant présente deux appareils pour lesquels le paramètre représentaient 50% et 40% du règlement sur les appareils. Une réécriture de la règle a permis d'améliorer considérablement la sécurité sans perte de fonctionnalité, comme indiqué ci-dessous. (Les appareils AOSP Shamu et Flounder sont inclus à titre de comparaison.)
Dans les deux cas, le règlement a été considérablement réduit, tant en termes de taille que de nombre
d'autorisations. La diminution de la taille des règles est presque entièrement due à la suppression
des autorisations inutiles, dont beaucoup sont probablement des règles
audit2allow
qui ont été ajoutés sans distinction au règlement. Mort
domaines posaient également
un problème pour les deux appareils.
Accorder la fonctionnalité dac_override
Un refus dac_override
signifie que le processus incriminé est
d’accéder à un fichier avec les
autorisations utilisateur/groupe/monde Unix incorrectes.
La bonne solution consiste presque jamais à accorder l'autorisation dac_override
.
À la place, <ph type="x-smartling-placeholder"></ph>
modifier les autorisations Unix sur le fichier ou le processus ; Quelques domaines tels que
init
, vold
et installd
ont réellement besoin
la possibilité d’ignorer les autorisations de fichier Unix
pour accéder aux fichiers d’autres processus.
Lire le blog de Dan Walsh
pour une explication plus détaillée.