Contrôle d'accès discrétionnaire (DAC)

Les objets et services du système de fichiers ajoutés à la construction ont souvent besoin d'identifiants distincts et uniques, appelés identifiants Android (AID). Actuellement, de nombreuses ressources telles que les fichiers et les services utilisent inutilement des AID de base (définis par Android) ; dans de nombreux cas, vous pouvez utiliser les aides OEM (définies par l'OEM) à la place.

Les versions antérieures d'Android (Android 7.x et versions antérieures) étendaient le mécanisme AID à l'aide d'un fichier android_filesystem_config.h spécifique à l'appareil pour spécifier les capacités du système de fichiers et/ou les AID OEM personnalisés. Cependant, ce système n'était pas intuitif car il ne prenait pas en charge l'utilisation de noms agréables pour les AID OEM, vous obligeant à spécifier le nombre brut pour les champs d'utilisateur et de groupe sans moyen d'associer un nom convivial à l'AID numérique.

Les nouvelles versions d'Android (Android 8.0 et versions ultérieures) prennent en charge une nouvelle méthode pour étendre les capacités du système de fichiers. Cette nouvelle méthode prend en charge les éléments suivants :

  • Plusieurs emplacements source pour les fichiers de configuration (permet des configurations de construction extensibles).
  • Vérification de l'intégrité au moment de la construction des valeurs OEM AID.
  • Génération d'un en-tête OEM AID personnalisé pouvant être utilisé dans les fichiers source selon les besoins.
  • Association d'un nom convivial avec la valeur OEM AID réelle. Prend en charge les arguments de chaîne non numériques pour l'utilisateur et le groupe, c'est-à-dire "foo" au lieu de "2901".

Des améliorations supplémentaires incluent la suppression du tableau android_ids[] de system/core/libcutils/include/private/android_filesystem_config.h . Ce tableau existe maintenant dans Bionic en tant que tableau généré entièrement privé, avec des accesseurs via getpwnam() et getgrnam() . (Cela a pour effet secondaire de produire des binaires stables lorsque les AID de base sont modifiés.) Pour les outils et un fichier README avec plus de détails, reportez-vous à build/make/tools/fs_config .

Ajout d'identifiants Android (AID)

Android 8.0 a supprimé le tableau android_ids[] du projet Android Open Source (AOSP). Tous les noms compatibles avec AID sont plutôt générés à partir du fichier d'en-tête system/core/libcutils/include/private/android_filesystem_config.h lors de la génération du tableau Bionic android_ids[] . Tout define AID_* correspondant à la définition est récupéré par l'outil et * devient le nom en minuscules.

Par exemple, dans private/android_filesystem_config.h :

#define AID_SYSTEM 1000

Devient:

  • Nom convivial : système
  • uid : 1000
  • gid : 1000

Pour ajouter un nouveau core AID AOSP, ajoutez simplement le #define au fichier d'en-tête android_filesystem_config.h . L'AID sera généré à la construction et mis à la disposition des interfaces qui utilisent des arguments d'utilisateur et de groupe. L'outillage valide que le nouvel AID n'est pas dans les plages APP ou OEM ; il respecte également les modifications apportées à ces plages et doit automatiquement reconfigurer les modifications ou les nouvelles plages réservées aux OEM.

Configuration des aides

Pour activer le nouveau mécanisme AID, définissez TARGET_FS_CONFIG_GEN dans le fichier BoardConfig.mk . Cette variable contient une liste de fichiers de configuration, vous permettant d'ajouter des fichiers selon vos besoins.

Par convention, les fichiers de configuration utilisent le nom config.fs , mais en pratique, vous pouvez utiliser n'importe quel nom. Les fichiers config.fs sont au format Python ConfigParser ini et incluent une section caps (pour configurer les fonctionnalités du système de fichiers) et une section AIDs (pour configurer les AID OEM).

Configuration de la section des majuscules

La section caps prend en charge la définition des capacités du système de fichiers sur les objets du système de fichiers dans la construction (le système de fichiers lui-même doit également prendre en charge cette fonctionnalité).

Étant donné que l'exécution d'un service stable en tant que racine dans Android entraîne une défaillance de la suite de tests de compatibilité (CTS) , les exigences précédentes pour conserver une capacité lors de l'exécution d'un processus ou d'un service impliquaient la configuration de capacités, puis l'utilisation de setuid / setgid pour un AID approprié à exécuter. Avec les majuscules, vous pouvez ignorer ces exigences et laisser le noyau le faire pour vous. Lorsque le contrôle est confié à main() , votre processus possède déjà les capacités dont il a besoin pour que votre service puisse utiliser un utilisateur et un groupe non root (c'est la méthode préférée pour démarrer des services privilégiés).

La section majuscules utilise la syntaxe suivante :

Section Évaluer Définition
[path] Le chemin du système de fichiers à configurer. Un chemin se terminant par / est considéré comme un répertoire, sinon c'est un fichier.

C'est une erreur de spécifier plusieurs sections avec le même [path] dans différents fichiers. Dans les versions Python <= 3.2, le même fichier peut contenir des sections qui remplacent la section précédente ; en Python 3.2, il est défini sur le mode strict.
mode Mode fichier octal Un mode de fichier octal valide d'au moins 3 chiffres. Si 3 est spécifié, il est préfixé par un 0, sinon le mode est utilisé tel quel.
user AID_<utilisateur> Soit le C define un AID valide, soit le nom convivial (par exemple AID_RADIO et radio sont acceptables). Pour définir un AID personnalisé, voir la section Configuration de l'AID .
group AID_<groupe> Identique à l'utilisateur.
caps casquette* Le nom tel que déclaré dans bionic/libc/kernel/uapi/linux/capability.h sans le premier CAP_ . Cas mixte autorisé. Les bouchons peuvent aussi être bruts :
  • binaire (0b0101)
  • octale (0455)
  • entier (42)
  • hexadécimal (0xFF)
Séparez plusieurs majuscules à l'aide d'espaces blancs.

Pour un exemple d'utilisation, consultez Utilisation des fonctionnalités du système de fichiers .

Configuration de la section AID

La section AID contient des AID OEM et utilise la syntaxe suivante :

Section Évaluer Définition
[AID_<name>] Le <name> peut contenir des caractères en majuscules, des chiffres et des traits de soulignement définis. La version minuscule est utilisée comme nom convivial. Le fichier d'en-tête généré pour l'inclusion de code utilise le AID_<name> exact.

C'est une erreur de spécifier plusieurs sections avec le même AID_<name> (insensible à la casse avec les mêmes contraintes que [path] ).

<name> doit commencer par un nom de partition pour s'assurer qu'il n'entre pas en conflit avec différentes sources.
value <nombre> Une chaîne de nombres de style C valide (hex, octal, binaire et décimal).

C'est une erreur de spécifier plusieurs sections avec la même option de valeur.

Les options de valeur doivent être spécifiées dans la plage correspondant à la partition utilisée dans <name> . La liste des partitions valides et leurs plages correspondantes sont définies dans system/core/libcutils/include/private/android_filesystem_config.h . Les options sont :
  • Partition fournisseur
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • Partition système
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • Partition ODM
    • AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • Partition de produit
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • Partition système_ext
    • AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

Pour obtenir des exemples d'utilisation, consultez Définition des noms d'AID OEM et Utilisation des AID OEM .

Exemples d'utilisation

Les exemples suivants détaillent comment définir et utiliser un OEM AID et comment activer les fonctionnalités du système de fichiers. Les noms AID OEM ( [AID_ name ] ) doivent commencer par un nom de partition tel que « vendor_ » pour s'assurer qu'ils n'entrent pas en conflit avec les futurs noms AOSP ou d'autres partitions.

Définition des noms OEM AID

Pour définir un AID OEM, créez un fichier config.fs et définissez la valeur AID. Par exemple, dans device/x/y/config.fs , définissez ce qui suit :

[AID_VENDOR_FOO]
value: 2900

Après avoir créé le fichier, définissez la variable TARGET_FS_CONFIG_GEN et pointez dessus dans BoardConfig.mk . Par exemple, dans device/x/y/BoardConfig.mk , définissez ce qui suit :

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

Votre AID personnalisé peut maintenant être consommé par le système dans son ensemble sur une nouvelle version.

Utilisation des aides OEM

Pour utiliser un OEM AID, dans votre code C, incluez les oemaids_headers dans votre Makefile associé, et ajoutez #include "generated_oem_aid.h" , puis commencez à utiliser les identifiants déclarés. Par exemple, dans my_file.c , ajoutez ce qui suit :

#include "generated_oem_aid.h"
…

If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

Dans votre fichier Android.bp associé, ajoutez les éléments suivants :

header_libs: ["oemaids_headers"],

Si vous utilisez un fichier Android.mk , ajoutez ce qui suit :

LOCAL_HEADER_LIBRARIES := oemaids_headers

Utiliser des noms conviviaux

Dans Android 9, vous pouvez utiliser le nom convivial pour toute interface prenant en charge les noms AID. Par exemple:

  • Dans une commande chown dans some/init.rc :
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • Dans un service dans some/init.rc :
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Étant donné que le mappage interne du nom convivial à l'uid est effectué par /vendor/etc/passwd et /vendor/etc/group , la partition du fournisseur doit être montée.

Associer des noms conviviaux

Android 9 inclut la prise en charge de l'association d'un nom convivial à la valeur réelle de l'AID OEM. Vous pouvez utiliser des arguments de chaîne non numériques pour l'utilisateur et le groupe, c'est-à-dire « vendeur_foo » au lieu de « 2901 ».

Conversion d'AID en noms conviviaux

Pour les aides OEM , Android 8.x nécessitait l'utilisation de oem_#### avec getpwnam et des fonctions similaires, ainsi qu'aux endroits qui gèrent les recherches via getpwnam (comme les scripts d' init ). Dans Android 9, vous pouvez utiliser les amis getpwnam et getgrnam dans Bionic pour convertir des identifiants Android (AID) en noms conviviaux et vice versa.

Utilisation des fonctionnalités du système de fichiers

Pour activer les fonctionnalités du système de fichiers, créez une section caps dans le fichier config.fs . Par exemple, dans device/x/y/config.fs , ajoutez la section suivante :

[system/bin/foo_service]
mode: 0555
user: AID_VENDOR_FOO
group: AID_SYSTEM
caps: SYS_ADMIN | SYS_NICE

Après avoir créé le fichier, définissez TARGET_FS_CONFIG_GEN pour qu'il pointe vers ce fichier dans BoardConfig.mk . Par exemple, dans device/x/y/BoardConfig.mk , définissez ce qui suit :

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

Lorsque le service vendor_ foo est exécuté, il démarre avec les capacités CAP_SYS_ADMIN et CAP_SYS_NICE sans appels setuid et setgid . De plus, la politique SELinux du service vendor_ foo n'a plus besoin des capacités setuid et setgid et peut être supprimée.

Configuration des remplacements (Android 6.x-7.x)

Android 6.0 a déplacé fs_config et les définitions de structure associées ( system/core/include/private/android_filesystem_config.h ) vers system/core/libcutils/fs_config.c où ils pourraient être mis à jour ou remplacés par des fichiers binaires installés dans /system/etc/fs_config_dirs et /system/etc/fs_config_files . L'utilisation de règles de correspondance et d'analyse distinctes pour les répertoires et les fichiers (qui pouvaient utiliser des expressions glob supplémentaires) a permis à Android de gérer les répertoires et les fichiers dans deux tables différentes. Les définitions de structure dans system/core/libcutils/fs_config.c non seulement la lecture à l'exécution des répertoires et des fichiers, mais l'hôte pouvait utiliser les mêmes fichiers pendant la construction pour construire des images de système de fichiers comme ${OUT}/system/etc/fs_config_dirs et ${OUT}/system/etc/fs_config_files .

Bien que la méthode de remplacement d'extension du système de fichiers ait été remplacée par le système de configuration modulaire introduit dans Android 8.0, vous pouvez toujours utiliser l'ancienne méthode si vous le souhaitez. Les sections suivantes détaillent comment générer et inclure des fichiers de remplacement et configurer le système de fichiers.

Génération de fichiers de remplacement

Vous pouvez générer les fichiers binaires alignés /system/etc/fs_config_dirs et /system/etc/fs_config_files à l'aide de l'outil fs_config_generate dans build/tools/fs_config . L'outil utilise une fonction de bibliothèque libcutils ( fs_config_generate() ) pour gérer les exigences DAC dans un tampon et définit des règles pour un fichier d'inclusion afin d'institutionnaliser les règles DAC.

Pour l'utiliser, créez un fichier d'inclusion dans device/ vendor / device /android_filesystem_config.h qui agit comme remplacement. Le fichier doit utiliser le format de structure fs_path_config défini dans system/core/include/private/android_filesystem_config.h avec les initialisations de structure suivantes pour les symboles de répertoire et de fichier :

  • Pour les répertoires, utilisez android _device _dirs[] .
  • Pour les fichiers, utilisez android _device _files[] .

Lorsque vous n'utilisez pas android_device_dirs[] et android_device_files[] , vous pouvez définir NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS et NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (voir l' exemple ci-dessous). Vous pouvez également spécifier le fichier de remplacement à l'aide de TARGET_ANDROID_FILESYSTEM_CONFIG_H dans la configuration de la carte, avec un nom de base appliqué android_filesystem_config.h .

Y compris les fichiers de remplacement

Pour inclure des fichiers, assurez-vous que PRODUCT_PACKAGES inclut fs_config_dirs et/ou fs_config_files afin qu'il puisse les installer respectivement dans /system/etc/fs_config_dirs et /system/etc/fs_config_files . Le système de construction recherche android_filesystem_config.h personnalisé dans $(TARGET_DEVICE_DIR) , où BoardConfig.mk existe. Si ce fichier existe ailleurs, définissez la variable de configuration de la carte TARGET_ANDROID_FILESYSTEM_CONFIG_H pour qu'elle pointe vers cet emplacement.

Configuration du système de fichiers

Pour configurer le système de fichiers dans Android 6.0 et supérieur :

  1. Créez le fichier $(TARGET_DEVICE_DIR)/android_filesystem_config.h .
  2. Ajoutez les fs_config_dirs et/ou fs_config_files à PRODUCT_PACKAGES dans le fichier de configuration de la carte (par exemple, $(TARGET_DEVICE_DIR)/device.mk ).

Remplacer l'exemple

Cet exemple montre un correctif pour remplacer le démon system/bin/glgps afin d'ajouter la prise en charge du verrouillage de réveil dans le répertoire device/ vendor / device . Gardez à l'esprit ce qui suit :

  • Chaque entrée de structure est le mode, l'uid, le gid, les capacités et le nom. system/core/include/private/android_filesystem_config.h est inclus automatiquement pour fournir le manifeste #defines ( AID_ROOT , AID_SHELL , CAP_BLOCK_SUSPEND ).
  • La section android_device_files[] inclut une action pour supprimer l'accès à system/etc/fs_config_dirs lorsqu'elle n'est pas spécifiée, qui sert de protection DAC supplémentaire en cas de manque de contenu pour les remplacements de répertoire. Cependant, il s'agit d'une protection faible ; si quelqu'un a le contrôle sur /system , il peut généralement faire tout ce qu'il veut.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h
new file mode 100644
index 0000000..874195f
--- /dev/null
+++ b/android_filesystem_config.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* This file is used to define the properties of the filesystem
+** images generated by build tools (eg: mkbootfs) and
+** by the device side of adb.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+/* static const struct fs_path_config android_device_dirs[] = { }; */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+static const struct fs_path_config android_device_files[] = {
+  { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND),
"system/bin/glgps" },
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+};


diff --git a/device.mk b/device.mk
index 0c71d21..235c1a7 100644
--- a/device.mk
+++ b/device.mk
@@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \
     libwpa_client \
     hostapd \
     wpa_supplicant \
-    wpa_supplicant.conf
+    wpa_supplicant.conf \
+    fs_config_files

 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)

Migration de systèmes de fichiers à partir de versions antérieures

Lors de la migration de systèmes de fichiers depuis Android 5.x et versions antérieures, gardez à l'esprit qu'Android 6.x

  • Supprime certaines inclusions, structures et définitions en ligne.
  • Nécessite une référence à libcutils au lieu de s'exécuter directement à partir de system/core/include/private/android_filesystem_config.h . Les exécutables privés du fabricant de l'appareil qui dépendent de system/code/include/private_filesystem_config.h pour les structures de fichiers ou de répertoires ou fs_config doivent ajouter des dépendances de bibliothèque libcutils .
  • Nécessite des copies de la branche privée du fabricant de l'appareil de system/core/include/private/android_filesystem_config.h avec du contenu supplémentaire sur les cibles existantes à déplacer vers device/ vendor / device /android_filesystem_config.h .
  • Se réserve le droit d'appliquer les contrôles d'accès obligatoires (MAC) SELinux aux fichiers de configuration sur le système cible, les implémentations qui incluent des exécutables cibles personnalisés à l'aide fs_config() doivent garantir l'accès.