Personnaliser SELinux

Après avoir intégré le niveau de base des fonctionnalités SELinux et analysés en détail les résultats, vous pouvez ajouter vos propres paramètres de politique pour couvrir vos personnalisations au système d'exploitation Android. Ces stratégies doivent toujours respecter le programme de compatibilité Android ; et vous ne devez pas supprimer les paramètres SELinux par défaut.

Les fabricants ne doivent pas supprimer les règles SELinux existantes. Sinon, il risquent de perturber l'implémentation d'Android SELinux et les applications qu'elle régit. Cela inclut les applications tierces qui devront probablement être améliorés pour assurer la conformité et le fonctionnement. Les applications ne doivent pas exiger modification pour continuer à fonctionner sur les appareils compatibles SELinux.

Lorsque vous commencez à personnaliser SELinux, n'oubliez pas:

  • Écrire des règles SELinux pour tous les nouveaux daemons
  • Utiliser des domaines prédéfinis chaque fois que nécessaire
  • Attribuer un domaine à tout processus généré en tant que service init
  • Familiarisez-vous avec les macros avant d'écrire des stratégies
  • Envoyer les modifications apportées au règlement principal dans AOSP

Et n'oubliez pas de ne pas:

  • Créer une règle incompatible
  • Autoriser la personnalisation des règles relatives aux utilisateurs finaux
  • Autoriser la personnalisation des règles MDM
  • Faire peur aux utilisateurs en cas de non-respect des règles
  • Ajouter des portes dérobées

Consultez la section Fonctionnalités de sécurité du noyau du document Sur Android document de définition de compatibilité pour connaître les exigences spécifiques.

SELinux utilise une approche de liste blanche, ce qui signifie que tous les accès doivent être explicitement autorisé dans la stratégie. Étant donné que la version par défaut est déjà compatible avec le projet Android Open Source, vous n'avez pas besoin modifier les paramètres SELinux de quelque manière que ce soit. Si vous personnalisez les paramètres SELinux, veillez à ne pas casser les applications existantes. Pour commencer :

  1. Utilisez les dernière version d'Android noyau.
  2. Adoptez les principe du moindre privilège.
  3. Ne traitez que les ajouts à Android. La stratégie par défaut fonctionne avec la plate-forme Android Open Source Project de votre projet.
  4. Compartmentez les composants logiciels en modules qui effectuent des tâches tâches.
  5. Créez des règles SELinux qui isolent ces tâches des tâches fonctions.
  6. Placez ces règles dans des fichiers *.te (l'extension de SELinux). fichiers sources de la règle) dans la section /device/manufacturer/device-name/sepolicy et utilisez les variables BOARD_SEPOLICY pour les inclure dans votre build.
  7. Rendre les nouveaux domaines permissifs au départ. Pour ce faire, utilisez un modèle permissif dans le fichier .te du domaine.
  8. Analysez les résultats et affinez vos définitions de domaine.
  9. Supprimez la déclaration permissive lorsqu'aucun autre refus ne s'affiche dans userdebug compilations.

Après avoir intégré la modification de votre règle SELinux, ajoutez une étape à votre de développement pour garantir la compatibilité avec SELinux à l'avenir. Dans un environnement processus de développement logiciel, la politique SELinux change uniquement lorsque le logiciel les modifications du modèle, et non l'implémentation proprement dite.

Lorsque vous commencez à personnaliser SELinux, vérifiez d'abord les ajouts à Android. Si vous avez ajouté un composant qui exécute une nouvelle fonction, assurez-vous que le composant respecte la politique de sécurité d'Android, ainsi que toute stratégie associée élaborée par l'OEM, avant d'activer le mode d'application.

Pour éviter les problèmes inutiles, il est préférable d’être trop général et est surcompatible, contrairement à une configuration trop restrictive ou incompatible, ce qui entraîne des erreurs les fonctions de l’appareil. À l'inverse, si vos modifications profitent à d'autres personnes, vous devez envoyez les modifications à la règle SELinux par défaut patch. Si le correctif est appliquée à la stratégie de sécurité par défaut, vous n'aurez pas besoin d'effectuer cette modification chaque nouvelle version d'Android.

Exemples de déclarations relatives au règlement

SELinux est basé sur M4 en langage informatique et prend donc en charge différentes macros pour gagner du temps.

Dans l'exemple suivant, tous les domaines ont un accès en lecture écrire dans /dev/null et lire à partir de /dev/zero.

# Allow read / write access to /dev/null
allow domain null_device:chr_file { getattr open read ioctl lock append write};

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file { getattr open read ioctl lock };

Cette même instruction peut être écrite à l'aide de la commande *_file_perms SELinux. (raccourci):

# Allow read / write access to /dev/null
allow domain null_device:chr_file rw_file_perms;

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file r_file_perms;

Exemple de stratégie

Voici un exemple complet de stratégie pour DHCP, que nous examinons ci-dessous:

type dhcp, domain;
permissive dhcp;
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;

init_daemon_domain(dhcp)
net_domain(dhcp)

allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service
};
allow dhcp self:packet_socket create_socket_perms;
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write };
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
# For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net:file write;
allow dhcp system_prop:property_service set ;
unix_socket_connect(dhcp, property, init)

type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;

allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };

Analysons cet exemple:

Dans la première ligne, la déclaration de type, le daemon DHCP hérite du stratégie de sécurité de base (domain). D'après la déclaration précédente exemples, le DHCP peut lire et écrire dans /dev/null.

Sur la deuxième ligne, le DHCP est identifié comme un domaine permissif.

Sur la ligne init_daemon_domain(dhcp), la règle indique que DHCP est généré à partir de init et est autorisé à communiquer avec lui.

Sur la ligne net_domain(dhcp), la règle permet au DHCP d'utiliser des fonctionnalités réseau courantes du domaine net, comme la lecture et écrire des paquets TCP, communiquer via des sockets et mener des requêtes.

À la ligne allow dhcp proc_net:file write;, la règle indique Le protocole DHCP peut écrire dans des fichiers spécifiques de /proc. Cette ligne illustre l'étiquetage précis des fichiers de SELinux ; Il utilise le libellé proc_net. pour limiter l'accès en écriture aux seuls fichiers sous /proc/sys/net.

Le dernier bloc de l'exemple, commençant par Le champ allow dhcp netd:fd use; décrit comment les applications peuvent être autorisées interagissent entre eux. La stratégie indique que DHCP et netd peuvent communiquer avec via des descripteurs de fichier, des fichiers FIFO, des sockets de datagramme et un flux UNIX sockets. Le DHCP ne peut lire et écrire que depuis les sockets de datagramme et UNIX les sockets de flux, et non de les créer ou de les ouvrir.

Commandes disponibles

Classe Autorisation
fichier
ioctl read write create getattr setattr lock relabelfrom relabelto append
unlink link rename execute swapon quotaon mounton
annuaire
add_name remove_name reparent search rmdir open audit_access execmod
prise
ioctl read write create getattr setattr lock relabelfrom relabelto append bind
connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg
name_bind
système de fichiers
mount remount unmount getattr relabelfrom relabelto transition associate
quotamod quotaget
processus
fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched
getsession getpgid setpgid getcap setcap share getattr setexec setfscreate
noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem
execstack execheap setkeycreate setsockcreate
sécurité
compute_av compute_create compute_member check_context load_policy
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot
read_policy
capacité
chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap
linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock
ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin
sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write
audit_control setfcap

PLUS

ET PLUS ENCORE

règles Neverallow

Les règles SELinux neverallow interdisent tout comportement qui ne devrait jamais se produire. Grâce aux tests de compatibilité, Les règles SELinux neverallow sont désormais appliquées sur tous les appareils.

Les consignes suivantes visent à aider les fabricants à éviter les erreurs. liée aux règles neverallow lors de la personnalisation. Les numéros des règles utilisés ici correspondent à Android 5.1 et sont susceptibles d'être modifiés selon les versions.

Règle 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Consultez la page de manuel concernant ptrace. sys_ptrace permet de ptrace n'importe quel processus, ce qui offre beaucoup sur les autres processus et doit appartenir uniquement au système désigné les composants, décrits dans la règle. Le besoin de cette fonctionnalité indique souvent la présence de quelque chose qui n'est pas destiné aux builds ou aux utilisateurs des fonctionnalités qui ne sont pas nécessaires. Supprimez le composant inutile.

Règle 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Cette règle vise à empêcher l'exécution de code arbitraire sur le système. Plus précisément, il affirme que seul le code sur /system est exécuté, ce qui permet des garanties de sécurité grâce à des mécanismes tels que le démarrage validé. Souvent, la meilleure solution en cas de problème la règle neverallow consiste à déplacer le code incriminé la partition /system.

Personnaliser SEPolicy sous Android 8.0 et versions ultérieures

Cette section fournit des consignes pour les règles SELinux du fournisseur dans Android 8.0 et plus haut, y compris les détails sur SEPolicy du projet Android Open Source (AOSP) et Extensions SEPolicy. Pour en savoir plus sur la façon dont la règle SELinux est conservée compatible avec les partitions et les versions d'Android, consultez Compatibilité :

Emplacement des stratégies

Dans Android 7.0 et versions antérieures, les fabricants d'appareils pouvaient ajouter des règles BOARD_SEPOLICY_DIRS, y compris les règles visant à compléter la stratégie AOSP sur différents types d'appareils. Dans Android 8.0 et versions ultérieures, l'ajout d'une règle BOARD_SEPOLICY_DIRS place la règle uniquement dans le fournisseur l'image.

Dans Android 8.0 et versions ultérieures, la règle existe aux emplacements suivants dans AOSP:

  • system/sepolicy/public. Inclut les règles exportées pour être utilisées dans les règles spécifiques aux fournisseurs. Android 8.0 contient tout ce qu'il faut infrastructure de compatibilité. Les règles publiques sont destinées à persister entre les versions afin que vous puissiez inclure /public dans votre règle personnalisée. Pour cette raison, le type de règle qui peut être placé dans /public est plus restreintes. Prenons l'exemple de l'API Policy exportée de la plate-forme: tout ce qui traite l'interface entre /system et /vendor est ici.
  • system/sepolicy/private. Inclut les règles nécessaires pour le fonctionnement de l'image système, mais la stratégie d'image du fournisseur sans aucune connaissance.
  • system/sepolicy/vendor. Inclut des règles pour les composants aller dans /vendor, mais dans l'arborescence principale de la plate-forme répertoires spécifiques à chaque appareil). Il s'agit d'un artefact de l'infrastructure distinguer les appareils des composants globaux ; conceptuellement, il s'agit de la règle spécifique à l'appareil décrite ci-dessous.
  • device/manufacturer/device-name/sepolicy. Inclut des règles spécifiques aux appareils. Inclut également les personnalisations d'appareils pour qui, dans Android 8.0 ou version ultérieure, correspond à la règle pour les composants sur l'image du fournisseur.

Sous Android 11 et versions ultérieures, les partitions "system_ext" et "product" peuvent également inclure propres aux partitions. Les règles system_ext et produit sont également divisées en public et privé, et les fournisseurs peuvent utiliser system_ext et le code public du produit des stratégies, comme la stratégie système.

  • SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS Inclut les règles exportées pour dans la règle spécifique au fournisseur. Installé sur la partition system_ext.
  • SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS Inclut les règles nécessaires pour le fonctionnement de l'image system_ext, mais de quelle image du fournisseur la politique ne devrait pas en avoir. Installé sur la partition system_ext.
  • PRODUCT_PUBLIC_SEPOLICY_DIRS Inclut les règles exportées pour dans la règle spécifique au fournisseur. Installé dans la partition des produits.
  • PRODUCT_PRIVATE_SEPOLICY_DIRS Inclut les règles nécessaires pour le fonctionnement de l'image du produit, ne devraient pas en avoir. Installé dans la partition des produits.
Remarque:Lorsque GSI est utilisé, les partitions system_ext et produit de l'OEM ne sont pas être installé. Les règles de la sepolicy du fournisseur qui utilisent les éléments system_ext et la politique publique du produit devient NOP, car les définitions de type spécifiques aux OEM sont sont manquantes.
Remarque:Soyez très prudent lorsque vous utilisez "system_ext" et les règles publiques de produit. Les règles publiques servent d'API exportées entre system_ext/product et le fournisseur. Les partenaires sont censés gérer eux-mêmes les problèmes de compatibilité.

Scénarios de règles acceptés

Sur les appareils équipés d'Android 8.0 ou version ultérieure, l'image du fournisseur doit fonctionner avec l'image système de l'OEM et l'image système AOSP de référence fournies par Google (et transmettre CTS sur cette image de référence). Ces exigences vous assurent entre le framework et le code du fournisseur. Ces appareils sont compatibles avec les scénarios suivants.

extensions d'image de fournisseur uniquement

Exemple: Ajouter un service à vndservicemanager de l'image du fournisseur qui prend en charge les processus à partir de l'image du fournisseur.

Comme pour les appareils lancés avec les versions précédentes d'Android, ajoutez des la personnalisation dans device/manufacturer/device-name/sepolicy Nouvelle règle régissant l'interaction des composants des fournisseurs avec les autres fournisseurs (uniquement) les composants doivent impliquer des types présents uniquement dans device/manufacturer/device-name/sepolicy. La règle écrite ici permet au code sur le fournisseur de fonctionner. Elle ne sera pas mise à jour dans le cadre du d'une OTA basée sur le framework uniquement, et seront présentes dans la stratégie combinée d'un appareil avec l'image système AOSP de référence.

de l'assistance d'images de fournisseurs avec AOSP

Exemple: Ajouter un nouveau processus (enregistré avec hwservicemanager à partir de l'image du fournisseur) qui implémente une HAL définie par AOSP.

Comme pour les appareils lancés avec les versions précédentes d'Android, de personnalisation spécifique à chaque appareil device/manufacturer/device-name/sepolicy La règle exportée dans system/sepolicy/public/ est disponible et est expédié conformément à la politique du fournisseur. Types et attributs de la stratégie publique peut être utilisée dans de nouvelles règles dictant les interactions bits spécifiques au fournisseur, soumis au neverallow fourni de restrictions. Comme pour le cas des fournisseurs uniquement, les nouvelles règles ne seront pas mises à jour dans le cadre d'une OTA basée sur le framework uniquement et seront incluses dans la stratégie combinée sur une avec l'image système AOSP de référence.

les extensions d'image système uniquement

Exemple: Ajouter un service (enregistré auprès de servicemanager) qui est accessible uniquement par d'autres processus à partir de l'image système.

Ajoutez cette règle à system/sepolicy/private. Vous pouvez ajouter des processus ou des objets pour activer des fonctionnalités dans une image système du partenaire, à condition ces nouveaux éléments n'ont pas besoin d'interagir avec les nouveaux composants sur l'image du fournisseur (plus précisément, de tels processus ou objets doivent fonctionner entièrement sans que la stratégie l'image du fournisseur). La règle exportée par system/sepolicy/public est disponible ici, tout comme pour les extensions d'image de fournisseur uniquement. Cette règle est de l'image système et pourrait être mise à jour dans une OTA uniquement basée sur le framework, absente lors de l'utilisation de l'image système AOSP de référence.

image du fournisseur extensions qui diffusent des composants AOSP étendus

Exemple:Un nouveau HAL non-AOSP destiné aux clients étendus qui existent également dans l'image système AOSP (par exemple, system_server étendu).

Les règles d'interaction entre le système et le fournisseur doivent être incluses dans le device/manufacturer/device-name/sepolicy envoyé sur la partition du fournisseur. Ce scénario est semblable au scénario ci-dessus, qui consiste à prendre en charge l'image du fournisseur pour fonctionner. avec l'image de référence AOSP, sauf que les composants AOSP modifiés peuvent également Exiger des règles supplémentaires pour fonctionner correctement avec le reste du système partition (ce qui est acceptable tant qu'ils disposent toujours du type AOSP public étiquettes).

Stratégie d'interaction des composants AOSP publics avec l'image système uniquement Les extensions doivent se trouver dans system/sepolicy/private.

image système Extensions qui n'accèdent qu'aux interfaces AOSP

Exemple:Un nouveau processus système non-AOSP doit accéder à un HAL sur sur lequel s'appuie AOSP.

Cette méthode est semblable à la commande system-image-only exemple d'extension, sauf que les nouveaux composants système peuvent interagir system/vendor. La règle du nouveau composant système le code system/sepolicy/private, ce qui est acceptable à condition qu'il soit via une interface déjà établie par AOSP system/sepolicy/public (c'est-à-dire les types et attributs obligatoires pour sont disponibles). Bien que la règle puisse être incluse dans les spécifications règle, il ne pourra pas utiliser d'autres system/sepolicy/private ni aucune modification (ayant une incidence sur les règles) qui résultent d'une mise à jour. Cette règle peut être modifiée dans une OTA basée sur le framework uniquement, mais elle ne le sera pas. lors de l'utilisation d'une image système AOSP (qui n'aura pas le nouveau système ).

image du fournisseur extensions qui diffusent de nouveaux composants système

Exemple:Ajouter un nouveau HAL non-AOSP à utiliser par un processus client sans analogue AOSP (et nécessite donc son propre domaine).

Semblable aux extensions AOSP, exemple, la règle concernant les interactions entre le système et le fournisseur doit être indiquée device/manufacturer/device-name/sepolicy répertoire envoyé sur la partition du fournisseur (pour garantir que la règle système n'a aucune connaissance des détails spécifiques au fournisseur). Toi pouvez ajouter de nouveaux types publics qui étendent la règle dans system/sepolicy/public; elle ne doit être faite qu'en plus politique AOSP existante, c'est-à-dire ne pas supprimer la politique publique d'AOSP. Le nouveau service public peuvent ensuite être utilisés pour la stratégie dans system/sepolicy/private et dans device/manufacturer/device-name/sepolicy

Gardez à l'esprit que chaque ajout à system/sepolicy/public ajoute la complexité en exposant une nouvelle garantie de compatibilité qui doit être suivie dans un de mappage et soumis à d'autres restrictions. Seuls les nouveaux types et règles d'autorisation correspondantes peuvent être ajoutées dans system/sepolicy/public. et d'autres instructions ne sont pas acceptées. De plus, les nouvelles Les types publics ne peuvent pas être utilisés pour étiqueter directement les objets dans Règle /vendor.

Scénarios de règles non compatibles

Les appareils équipés d'Android 8.0 ou version ultérieure ne sont pas compatibles avec les fonctionnalités suivantes : de stratégie et des exemples.

Autres Extensions d'image système nécessitant une autorisation aux nouveaux composants d'image du fournisseur après une OTA uniquement basée sur le framework

Exemple : Un nouveau processus système non-AOSP nécessitant son propre est ajouté dans la prochaine version d'Android et a besoin d'accéder à une nouvelle HAL non-AOSP.

Semblable à neuf Interaction avec le système et les composants du fournisseur (non-AOSP), à l'exception du nouveau système est introduit dans une OTA basée sur le framework uniquement. Bien que le nouveau type puisse être ajouté à la stratégie dans system/sepolicy/public, le règlement existant relatif aux fournisseurs n'a aucune connaissance du nouveau type, car il ne suit que la politique publique du système Android 8.0. AOSP résout ce problème en exposant les ressources fournies par le fournisseur via un attribut (par exemple, hal_foo), mais les extensions de partenaire ne le sont pas en tant qu'attribut disponible dans system/sepolicy/public, cette méthode n'est pas disponible pour les règles relatives aux fournisseurs. L'accès doit être fourni par un type public existant.

Exemple : Une modification d'un processus système (AOSP ou non-AOSP) doit modifier la façon dont il interagit avec un nouveau composant de fournisseur non-AOSP.

La stratégie de l'image système doit être écrite sans connaître les personnalisations des fournisseurs. La règle concernant des interfaces spécifiques dans AOSP est donc exposées via des attributs dans system/sepolicy/public afin que la règle du fournisseur puisse accepter les futures règles du système qui utilisent ces attributs. Toutefois, Les extensions d'attributs dans system/sepolicy/public ne sont pas sont compatibles, donc toutes les règles dictant la façon dont les composants du système interagissent avec de nouveaux composants de fournisseurs (et qui n'est pas déjà géré par des attributs) présente dans AOSP system/sepolicy/public) doit se trouver dans device/manufacturer/device-name/sepolicy Cela signifie que les types de systèmes ne peuvent pas l'accès autorisé aux types de fournisseurs dans le cadre d'une OTA uniquement au framework.