SELinux est configuré pour refuser par défaut, ce qui signifie que chaque accès pour lequel il dispose d'un crochet dans le noyau doit être explicitement autorisé par la stratégie. Cela signifie qu'un fichier de règles comprend une grande quantité d'informations sur les règles, les types, les classes, les autorisations, etc. L'étude complète de SELinux n'entre pas dans le champ d'application de ce document, mais il est désormais essentiel de savoir écrire des règles de stratégie lors de la mise en service de nouveaux appareils Android. De nombreuses informations sont déjà disponibles sur SELinux. Pour obtenir des suggestions de ressources, consultez la section Documentation complémentaire.
Fichiers de clé
Pour activer SELinux, intégrez le dernier kernel Android, puis incorporez les fichiers trouvés dans le répertoire system/sepolicy. Lors de la compilation, ces fichiers comprennent la stratégie de sécurité du noyau SELinux et couvrent le système d'exploitation Android en amont.
En règle générale, vous ne devez pas modifier directement les fichiers system/sepolicy
. À la place, ajoutez ou modifiez vos propres fichiers de stratégie spécifiques à l'appareil dans le répertoire /device/manufacturer/device-name/sepolicy
. Sous Android 8.0 ou version ultérieure, les modifications que vous apportez à ces fichiers ne devraient affecter que les règles de votre répertoire de fournisseurs. Pour en savoir plus sur la séparation de la stratégie de sécurité publique dans Android 8.0 et versions ultérieures, consultez Personnaliser SEPolicy dans Android 8.0 et versions ultérieures. Quelle que soit la version d'Android, vous modifiez toujours ces fichiers:
Fichiers de règles
Les fichiers se terminant par *.te
sont des fichiers sources de règles SELinux, qui définissent les domaines et leurs libellés. Vous devrez peut-être créer des fichiers de règles dans /device/manufacturer/device-name/sepolicy
, mais vous devez essayer de mettre à jour les fichiers existants dans la mesure du possible.
Fichiers de contexte
Les fichiers de contexte vous permettent de spécifier des libellés pour vos objets.
file_contexts
attribue des libellés aux fichiers et est utilisé par divers composants d'espace utilisateur. Lorsque vous créez des règles, créez ou mettez à jour ce fichier pour attribuer de nouveaux libellés aux fichiers. Pour appliquer un nouveaufile_contexts
, reconstruisez l'image du système de fichiers ou exécutezrestorecon
sur le fichier à rebaptiser. Lors des mises à niveau, les modifications apportées àfile_contexts
sont automatiquement appliquées aux partitions système et userdata. Les modifications peuvent également être appliquées automatiquement lors de la mise à niveau vers d'autres partitions en ajoutant des appelsrestorecon_recursive
à votre fichier init.board.rc après le montage en lecture-écriture de la partition.genfs_contexts
attribue des libellés aux systèmes de fichiers, tels queproc
ouvfat
, qui ne sont pas compatibles avec les attributs étendus. Cette configuration est chargée dans le cadre de la stratégie du noyau, mais les modifications peuvent ne pas prendre effet pour les nœuds d'index du noyau, ce qui nécessite un redémarrage ou un démontage et un nouveau montage du système de fichiers pour appliquer complètement la modification. Des libellés spécifiques peuvent également être attribués à des montages spécifiques, tels quevfat
à l'aide de l'optioncontext=mount
.property_contexts
attribue des libellés aux propriétés du système Android pour contrôler les processus qui peuvent les définir. Cette configuration est lue par le processusinit
au démarrage.service_contexts
attribue des libellés aux services de liaison Android pour contrôler les processus pouvant ajouter (enregistrer) et rechercher (rechercher) une référence de liaison pour le service. Cette configuration est lue par le processusservicemanager
au démarrage.seapp_contexts
attribue des libellés aux processus d'application et aux répertoires/data/data
. Cette configuration est lue par le processuszygote
à chaque lancement d'application et parinstalld
au démarrage.mac_permissions.xml
attribue une baliseseinfo
aux applications en fonction de leur signature et éventuellement de leur nom de package. La baliseseinfo
peut ensuite être utilisée comme clé dans le fichierseapp_contexts
pour attribuer un libellé spécifique à toutes les applications associées à cette baliseseinfo
. Cette configuration est lue parsystem_server
au démarrage.keystore2_key_contexts
attribue des libellés aux espaces de noms Keystore 2.0. Ces espaces de noms sont appliqués par le daemon keystore2. Le keystore a toujours fourni des espaces de noms basés sur des UID/AID. Keystore 2.0 applique également les espaces de noms définis par sepolicy. Pour en savoir plus sur le format et les conventions de ce fichier, cliquez ici.
Fichier makefile BoardConfig.mk
Après avoir modifié ou ajouté des fichiers de règles et de contexte, mettez à jour votre fichier de compilation /device/manufacturer/device-name/BoardConfig.mk
pour référencer le sous-répertoire sepolicy
et chaque nouveau fichier de règles.
Pour en savoir plus sur les variables BOARD_SEPOLICY
, consultez le
fichier system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Après la recompilation, SELinux est activé sur votre appareil. Vous pouvez désormais personnaliser vos règles SELinux pour prendre en charge vos propres ajouts au système d'exploitation Android, comme décrit dans la section Personnalisation, ou vérifier votre configuration existante, comme décrit dans la section Validation.
Lorsque les nouveaux fichiers de règles et les mises à jour de BoardConfig.mk sont en place, les nouveaux paramètres de règles sont automatiquement intégrés au fichier de règles du kernel final. Pour en savoir plus sur la création de sepolicy sur l'appareil, consultez la section Créer sepolicy.
Implémentation
Pour commencer à utiliser SELinux:
- Activez SELinux dans le noyau :
CONFIG_SECURITY_SELINUX=y
- Modifiez le paramètre kernel_cmdline ou bootconfig afin que:
ouBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
Cette option ne sert qu'au développement initial de la stratégie pour l'appareil. Une fois que vous avez une règle de démarrage initiale, supprimez ce paramètre pour que votre appareil applique la règle ou échoue au CTS.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- Démarrez le système en mode permissif et vérifiez les refus rencontrés au démarrage:
Sur Ubuntu 14.04 ou version ultérieure: Sous Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Examinez la sortie pour rechercher des avertissements ressemblant à
init: Warning! Service name needs a SELinux domain defined; please fix!
. Consultez la section Validation pour obtenir des instructions et des outils. - Identifiez les appareils et les autres nouveaux fichiers qui doivent être libellés.
- Utilisez des libellés existants ou créez-en de nouveaux pour vos objets. Examinez les fichiers
*_contexts
pour voir comment les éléments étaient précédemment libellés et utilisez vos connaissances sur la signification des libellés pour en attribuer un nouveau. Idéalement, il s'agit d'un libellé existant qui respecte le règlement, mais il est parfois nécessaire de créer un nouveau libellé et des règles d'accès à ce libellé. Ajoutez vos libellés aux fichiers de contexte appropriés. - Identifiez les domaines/processus qui doivent disposer de leurs propres domaines de sécurité.
Vous devrez probablement écrire une règle complètement différente pour chacune d'elles. Par exemple, tous les services créés à partir de
init
doivent en avoir un. Les commandes suivantes permettent de révéler ceux qui restent en cours d'exécution (mais TOUS les services ont besoin d'un tel traitement):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Examinez
init.device.rc
pour identifier les domaines qui ne disposent pas d'un type de domaine. Attribuez-leur un domaine dès le début du processus de développement pour éviter d'ajouter des règles àinit
ou de confondre les accèsinit
avec ceux qui figurent dans leur propre stratégie. - Configurez
BOARD_CONFIG.mk
pour utiliser des variablesBOARD_SEPOLICY_*
. Pour savoir comment configurer cette fonctionnalité, consultez le fichier README danssystem/sepolicy
. - Examinez les fichiers init.device.rc et fstab.device, et assurez-vous que chaque utilisation de
mount
correspond à un système de fichiers correctement libellé ou qu'une optioncontext= mount
est spécifiée. - Passez en revue chaque refus et créez une règle SELinux pour gérer correctement chacun d'eux. Consultez les exemples dans la section Personnalisation.
Vous devez commencer par les règles de l'AOSP, puis les développer pour vos propres personnalisations. Pour en savoir plus sur la stratégie de stratégie et pour examiner de plus près certaines de ces étapes, consultez la section Écrire des règles SELinux.
Cas d'utilisation
Voici des exemples spécifiques d'exploits à prendre en compte lorsque vous créez votre propre logiciel et les règles SELinux associées:
Liens symboliques:comme les liens symboliques apparaissent comme des fichiers, ils sont souvent lus comme des fichiers, ce qui peut entraîner des exploitations. Par exemple, certains composants privilégiés, tels que init
, modifient les autorisations de certains fichiers, parfois de manière excessive.
Les pirates informatiques peuvent ensuite remplacer ces fichiers par des liens symboliques vers du code qu'ils contrôlent, ce qui leur permet d'écraser des fichiers arbitraires. Toutefois, si vous savez que votre application ne traverse jamais de lien symbolique, vous pouvez l'en empêcher avec SELinux.
Fichiers système:classe de fichiers système qui ne doivent être modifiés que par le serveur système. Toutefois, comme netd
, init
et vold
s'exécutent en tant que racine, ils peuvent accéder à ces fichiers système. Par conséquent, si netd
est compromis, il peut compromettre ces fichiers et potentiellement le serveur système lui-même.
Avec SELinux, vous pouvez identifier ces fichiers comme des fichiers de données de serveur système.
Par conséquent, le seul domaine qui dispose d'un accès en lecture/écriture est le serveur système.
Même si netd
était compromis, il ne pouvait pas passer au domaine du serveur système et accéder à ces fichiers système, même s'il s'exécute en tant que root.
Données d'application : autre exemple : la classe de fonctions qui doit s'exécuter en tant que root, mais qui ne doit pas accéder aux données de l'application. Cela est extrêmement utile, car des affirmations très larges peuvent être faites, par exemple que certains domaines sans rapport avec les données de l'application sont interdits d'accéder à Internet.
setattr:pour les commandes telles que chmod
et chown
, vous pouvez identifier l'ensemble de fichiers dans lesquels le domaine associé peut effectuer des setattr
. Tout ce qui n'est pas inclus dans cette liste peut être interdit de ces modifications, même par le root. Par conséquent, une application peut exécuter chmod
et chown
sur les éléments marqués app_data_files
, mais pas sur shell_data_files
ou system_data_files
.