Format de fichier APEX

Le format de conteneur Android Pony EXpress (APEX) a été introduit dans Android 10. Il est utilisé dans le flux d'installation pour les systèmes de niveau inférieur modules. Ce format facilite la mise à jour des composants système qui ne conviennent pas au modèle d'application Android standard. Certains exemples de composants sont natifs des services et bibliothèques, des couches d'abstraction matérielle (HAL), environnement d'exécution (ART) et les bibliothèques de classes.

Le terme "APEX" peut également faire référence à un fichier APEX.

Arrière-plan

Bien qu'Android prenne en charge les mises à jour de modules qui s'intègrent à l'application standard (services ou activités, par exemple) via des applications d'installation de packages (telles que l'application Google Play Store), en utilisant un modèle similaire pour les composants de l'OS de niveau inférieur présente les inconvénients suivants:

  • Les modules basés sur APK ne peuvent pas être utilisés au début de la séquence de démarrage. Le package est le référentiel central des informations sur les applications. Il ne peut être a démarré à partir du gestionnaire d'activités, qui est prêt la procédure de démarrage.
  • Le format de l'APK (en particulier le fichier manifeste) est conçu pour les applications Android et les modules système ne sont pas toujours un bon choix.

Conception

Cette section décrit la conception générale du format de fichier APEX et le APEX Manager, qui est un service qui gère les fichiers APEX.

Pour savoir pourquoi cette conception pour les apex a été sélectionnée, consultez Alternatives envisagées lors du développement d'APEX.

Format APEX

Il s'agit du format d'un fichier APEX.

Format de fichier APEX

Figure 1 : Format de fichier APEX

De manière générale, un fichier APEX est un fichier ZIP dans lequel les fichiers sont stockés non compressées et situées à des limites de 4 Ko.

Les quatre fichiers d'un fichier APEX sont les suivants:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

Le fichier apex_manifest.json contient le nom et la version du package, qui identifier un fichier APEX. Il s'agit d'un ApexManifest Protocol Buffer au format JSON.

Le fichier AndroidManifest.xml permet au fichier APEX d'utiliser les outils liés à l'APK et infrastructure comme ADB, PackageManager, et les applications du programme d'installation de packages (telles que Play Store). Par exemple, le fichier APEX peut utiliser un outil existant tel que aapt. pour inspecter les métadonnées de base du fichier. Le fichier contient le nom du package et les informations de version. Ces informations sont généralement également disponibles dans apex_manifest.json

apex_manifest.json est recommandé par rapport à AndroidManifest.xml pour le nouveau code et des systèmes qui gèrent les APEX. AndroidManifest.xml peut contenir informations de ciblage utilisables par les outils de publication d'applications existants.

apex_payload.img est une image de système de fichiers ext4 reposant sur dm-verity. L'image est installé au moment de l'exécution via un appareil de bouclage. Plus précisément, l'arborescence de hachage et un bloc de métadonnées est créé à l'aide de la bibliothèque libavb. La charge utile du système de fichiers n'est pas analysée (car l'image doit pouvoir être installée sur place). Les fichiers standards sont inclus dans le fichier apex_payload.img.

apex_pubkey est la clé publique utilisée pour signer l'image du système de fichiers. Au moment de l'exécution, cette clé garantit que l'apex téléchargé est signé avec la même entité qui signe le même APEX dans les partitions intégrées.

Consignes de dénomination des apex

Pour éviter les conflits de noms entre les nouveaux APEX à mesure que la plate-forme évolue, Suivez les consignes de dénomination suivantes:

  • com.android.*
    • Réservé pour les AOSP APEX. Elle n'est pas propre à toutes les entreprises ni à tous les appareils.
  • com.<companyname>.*
    • Réservé à une entreprise. Peut être utilisé par plusieurs appareils à partir de celui-ci entreprise.
  • com.<companyname>.<devicename>.*
    • Réservé pour les APEX propres à un appareil spécifique (ou à un sous-ensemble d'appareils).

Gestionnaire d'apex

Le gestionnaire APEX (ou apexd) est un processus natif autonome chargé de vérifier, installer et désinstaller les fichiers APEX. Ce processus est lancé et est prêt au début de la séquence de démarrage. Les fichiers APEX sont normalement préinstallés sur l'appareil sous /system/apex. Par défaut, le gestionnaire d'apex utilise ces packages si aucune mise à jour n'est disponible.

La séquence de mise à jour d'un APEX utilise le Classe PackageManager et se présente comme suit.

  1. Un fichier APEX est téléchargé via un programme d’installation de packages, ADB ou un autre source.
  2. Le gestionnaire de packages lance la procédure d'installation. Après avoir reconnu que le fichier est un APEX, le gestionnaire de packages transfère le contrôle à responsable.
  3. Le gestionnaire APEX valide le fichier APEX.
  4. Si le fichier APEX est validé, la base de données interne du gestionnaire APEX est mis à jour pour indiquer que le fichier APEX s’active au prochain démarrage.
  5. Le demandeur d'installation reçoit une annonce lorsque le package réussit la validation.
  6. Pour continuer l'installation, vous devez redémarrer le système.
  7. Au prochain démarrage, APEX Manager démarre, lit la base de données interne pour chaque fichier APEX listé:

    1. Vérifie le fichier APEX.
    2. Crée un appareil de rebouclage à partir du fichier APEX.
    3. Crée un appareil de mappage d'appareils en mode bloc au-dessus de l'appareil de rebouclage.
    4. Il installe l'appareil en mode bloc de mappage d'appareils sur un chemin d'accès unique (par exemple, /apex/name@ver).

Une fois que tous les fichiers APEX répertoriés dans la base de données interne sont installés, fournit un service de liaison permettant à d'autres composants du système d'interroger des informations sur les fichiers APEX installés. Par exemple, l'autre système les composants peuvent interroger la liste des fichiers APEX installés sur l'appareil ou interroger chemin exact où un APEX spécifique est installé, afin que les fichiers soient accessibles.

Les fichiers APEX sont des fichiers APK

Les fichiers APEX sont des fichiers APK valides, car il s'agit d'archives ZIP signées (à l'aide de la méthode schéma de signature APK) contenant un fichier AndroidManifest.xml. Cela permet à APEX pour utiliser l'infrastructure pour les fichiers APK, comme un programme d'installation de packages, l'utilitaire de signature et le gestionnaire de packages.

Le fichier AndroidManifest.xml d'un fichier APEX est minimal : il se compose des éléments suivants : le package name, versionCode, et les targetSdkVersion, minSdkVersion (facultatif) et maxSdkVersion pour un ciblage plus précis. Ces informations permettent à APEX les fichiers à distribuer via des canaux existants, tels que les applications d’installation de packages et ADB.

Types de fichiers compatibles

Le format APEX est compatible avec les types de fichiers suivants:

  • Bibliothèques partagées natives
  • Exécutables natifs
  • Fichiers JAR
  • Fichiers de données
  • Fichiers de configuration

Cela ne signifie pas qu'APEX peut mettre à jour tous ces types de fichiers. Si un fichier peut être mis à jour dépend de la plate-forme et de la stabilité des définitions de les interfaces pour les types de fichiers sont.

Options de signature

Les fichiers APEX sont signés de deux manières. Tout d'abord, le apex_payload.img (plus précisément, (le descripteur vbmeta ajouté à apex_payload.img) est signé avec une clé. Ensuite, l'intégralité de l'apex est signée à l'aide du APK Signature Scheme v3 : Deux clés différentes sont utilisées dans ce processus.

Côté appareil, une clé publique correspondant à la clé privée utilisée pour signer le descripteur vbmeta est installé. Le gestionnaire APEX utilise la clé publique pour vérifier les APEX dont l’installation est demandée. Chaque APEX doit être signé avec différentes clés et est appliqué au moment de la compilation et de l'exécution.

APEX dans les partitions intégrées

Les fichiers APEX peuvent se trouver dans des partitions intégrées telles que /system. La est déjà sur dm-verity, les fichiers APEX sont donc installés directement sur l'appareil de bouclage.

Si un APEX est présent dans une partition intégrée, il peut être mis à jour en fournir un package APEX avec le même nom de package et une valeur supérieure ou égale au code de version. Le nouvel APEX est stocké dans /data et, comme les APK, la version qui vient d'être installée masque la version déjà présente dans la partition. Mais contrairement aux APK, la version nouvellement installée de l'APEX n'est activée après le redémarrage.

Exigences du noyau

Pour prendre en charge les modules principaux APEX sur un appareil Android, les composants Linux suivants les fonctionnalités du noyau sont requises: le pilote de bouclage et dm-verity. Le bouclage le pilote installe l'image du système de fichiers dans un module APEX, et dm-verity vérifie APEX.

Les performances du pilote de bouclage et de dm-verity sont importantes de bonnes performances du système lors de l'utilisation de modules APEX.

Versions de noyau compatibles

Les modules principaux APEX sont compatibles avec les appareils utilisant les versions de noyau 4.4 ou plus élevée. les nouveaux appareils équipés d'Android 10 ou version ultérieure ; doivent utiliser la version 4.9 ou une version ultérieure du noyau pour prendre en charge les modules APEX.

Correctifs de noyau requis

Les correctifs du noyau nécessaires à la prise en charge des modules APEX sont inclus dans le Arbre commun d'Android. Pour obtenir les correctifs compatibles avec APEX, utilisez la dernière version de l'arborescence commune d'Android.

Noyau version 4.4

Cette version n'est compatible qu'avec les appareils mis à niveau d'Android 9 vers Android 10 et que vous souhaitez prendre en charge les modules APEX. Pour obtenir les correctifs requis, une fusion descendante à partir de la branche android-4.4 est fortement recommandé. Voici une liste des correctifs individuels requis pour la version de noyau 4.4.

  • UPSTREAM: loop: ajouter ioctl pour modifier la taille de bloc logique (4.4)
  • RETOUR ARRIÈRE: bloc/boucle: définition de hw_sectors (4.4)
  • UPSTREAM: boucle: ajouter LOOP_SET_BLOCK_SIZE dans ioctl (4.4)
  • ANDROID: mnt: correction de next_descendent (4.4)
  • ANDROID: mnt: le réinstallation devrait se propager aux esclaves des esclaves (4.4)
  • ANDROID: mnt: Propager le réinstallation correctement (4.4)
  • Rétablir "ANDROID : dm verity: add minimum prefetch size" (ANDROID : dm verity : ajouter une taille de préchargement minimale) (4.4)
  • UPSTREAM: boucle: suppression des caches si offset ou block_size sont modifiés (4.4)

Versions du noyau 4.9/4.14/4.19

Pour obtenir les correctifs requis pour les versions de noyau 4.9/4.14/4.19, effectuez une fusion descendante la branche android-common.

Options de configuration du noyau requises

La liste suivante présente les exigences de configuration de base pour la prise en charge Modules APEX introduits dans Android 10. Les éléments comportant un astérisque (*) pour Android 9 ou version antérieure.

(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support

Exigences relatives aux paramètres de ligne de commande du kernel

Pour assurer la compatibilité avec APEX, assurez-vous que les paramètres de ligne de commande du noyau répondent aux critères suivants configuration requise:

  • loop.max_loop NE DOIT PAS être défini
  • loop.max_part doit être inférieur ou égal à 8.

Créer un APEX

Cette section explique comment compiler un APEX à l'aide du système de compilation Android. Voici un exemple de Android.bp pour un apex nommé apex.test.

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

Exemple pour apex_manifest.json:

{
  "name": "com.android.example.apex",
  "version": 1
}

Exemple pour file_contexts:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

Types et emplacements de fichiers dans APEX

Type de fichier Emplacement dans APEX
Photothèques partagées /lib et /lib64 (/lib/arm pour groupe traduit dans x86)
Fichiers exécutables /bin
Bibliothèques Java /javalib
Prédéfinis /etc

Dépendances transitives

Les fichiers APEX incluent automatiquement les dépendances transitives des bibliothèques partagées natives ou exécutables. Par exemple, si libFoo dépend de libBar, les deux bibliothèques sont inclus lorsque seul libFoo est répertorié dans la propriété native_shared_libs.

Gérer plusieurs ABI

Installer la propriété native_shared_libs pour l'instance principale et l'instance secondaire les interfaces binaires d'application (ABI) de l'appareil. Si un APEX cible des appareils avec une seule ABI (c'est-à-dire 32 bits ou 64 bits uniquement), uniquement les bibliothèques avec l'ABI correspondante sont installées.

Installez la propriété binaries uniquement pour l'ABI principale de l'appareil, en tant que décrits ci-dessous:

  • Si le périphérique est uniquement 32 bits, seule la variante 32 bits du binaire est installés.
  • Si le périphérique est uniquement 64 bits, alors seule la variante 64 bits du binaire est installés.

Pour ajouter un contrôle précis sur les ABI des bibliothèques natives et des binaires, utilisez la multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] propriétés.

  • first: correspond à l'ABI principale de l'appareil. Il s'agit du paramètre par défaut binaires.
  • lib32: correspond à l'ABI 32 bits de l'appareil, si compatible.
  • lib64: correspond à l'ABI 64 bits de l'appareil (compatible).
  • prefer32: correspond à l'ABI 32 bits de l'appareil, si compatible. Si le L'ABI 32 bits n'est pas compatible. Elle correspond à l'ABI 64 bits.
  • both: correspond aux deux ABI. Il s'agit du paramètre par défaut native_shared_libraries

Les propriétés java, libraries et prebuilts sont indépendantes des ABI.

Cet exemple concerne un appareil qui prend en charge le 32/64, mais ne préfère pas le 32:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

signature vbmeta

Signez chaque APEX avec des clés différentes. Lorsqu'une nouvelle clé est requise, paire de clés publique-privée et créer un module apex_key. Utilisez la propriété key pour signer l'apex à l'aide de la clé. La clé publique est automatiquement incluse dans APEX nommé avb_pubkey.

# create an rsa key pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_key {
    name: "apex.test.key",
    public_key: "foo.avbpubkey",
    private_key: "foo.pem",
}

Dans l'exemple ci-dessus, le nom de la clé publique (foo) devient l'ID de la . L'ID de la clé utilisée pour signer un APEX est écrit dans l'APEX. Au moment de l'exécution, apexd vérifie l'apex à l'aide d'une clé publique ayant le même ID sur l'appareil.

Signature APEX

Signez les apex de la même manière que les APK. signer les apex deux fois ; une fois pour (fichier apex_payload.img) et une fois pour l'intégralité du fichier.

Pour signer un APEX au niveau du fichier, définissez la propriété certificate dans l'une des de ces trois manières:

  • Non défini: si aucune valeur n'est définie, l'apex est signé avec le certificat situé à PRODUCT_DEFAULT_DEV_CERTIFICATE. Si aucune option n'est définie, le chemin d'accès par défaut à build/target/product/security/testkey.
  • <name>: l'apex est signé avec le certificat <name> dans le même en tant que PRODUCT_DEFAULT_DEV_CERTIFICATE.
  • :<name>: l'apex est signé avec le certificat défini par le Module Soong nommé <name>. Le module de certificat peut être défini comme suit.
android_app_certificate {
    name: "my_key_name",
    certificate: "dir/cert",
    // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}

Installer un APEX

Pour installer un APEX, utilisez ADB.

adb install apex_file_name
adb reboot

Si supportsRebootlessUpdate est défini sur true dans apex_manifest.json et que le paramètre actuellement installé n'est pas utilisé (par exemple, tous les services qu'il contient ont a été arrêté), un nouvel APEX peut être installé sans redémarrage à l'aide de --force-non-staged.

adb install --force-non-staged apex_file_name

Utiliser un APEX

Après le redémarrage, l'APEX est installé sur /apex/<apex_name>@<version> . Plusieurs versions du même APEX peuvent être installées en même temps. Parmi les chemins d'accès au montage, celui qui correspond à la dernière version est monté en liaison sur /apex/<apex_name>.

Les clients peuvent utiliser le chemin d'accès monté par liaison pour lire ou exécuter des fichiers à partir d'APEX.

Les apex sont généralement utilisés comme suit:

  1. Un OEM ou ODM précharge un APEX sous /system/apex lorsque l'appareil est expédiés.
  2. Les fichiers de l'apex sont accessibles via le chemin d'accès /apex/<apex_name>/.
  3. Lorsqu'une version mise à jour de l'APEX est installée dans /data/apex, le chemin d'accès pointe vers le nouvel APEX après le redémarrage.

Mettre à jour un service avec un APEX

Pour mettre à jour un service à l'aide d'un APEX:

  1. Marquez le service dans la partition système comme pouvant être mis à jour. Ajouter l'option updatable à la définition de service.

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. Créez un fichier .rc pour le service mis à jour. Utiliser l'option override pour redéfinir le service existant.

    /apex/my.apex/etc/init.rc:
    
    service myservice /apex/my.apex/bin/myservice
        class core
        user system
        ...
        override
    

Les définitions de service ne peuvent être définies que dans le fichier .rc d'un APEX. Action les déclencheurs ne sont pas compatibles avec les apex.

Si un service marqué comme pouvant être mis à jour démarre avant l'activation des APEXes, le est retardé jusqu'à ce que l'activation des APEX soit terminée.

Configurer le système pour qu'il accepte les mises à jour APEX

Définissez la propriété système suivante sur true pour prendre en charge les mises à jour des fichiers APEX.

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

ou simplement

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

Apex aplati

Pour les anciens appareils, il est parfois impossible ou impossible de mettre à jour les anciens noyau pour prendre en charge entièrement APEX. Par exemple, le noyau peut avoir été compilé sans CONFIG_BLK_DEV_LOOP=Y, ce qui est essentiel pour installer le système de fichiers. dans un élément APEX.

Flattened APEX est un APEX spécialement qui peut être activé sur les appareils avec un noyau hérité. Les fichiers d'un APEX aplati sont directement installés dans un répertoire sous la partition intégrée. Par exemple, lib/libFoo.so dans un apex aplati my.apex est installé dans /system/apex/my.apex/lib/libFoo.so.

L'activation d'un APEX aplati n'implique pas l'appareil en boucle. L'intégralité Le répertoire /system/apex/my.apex est directement associé à /apex/name@ver.

Les APEX aplatis ne peuvent pas être mis à jour en téléchargeant les versions mises à jour des APEX du réseau, car les APEX téléchargés ne peuvent pas être aplatis. Les APEX aplatis ne peuvent être mis à jour que via une OTA standard.

La valeur Flattened APEX est la configuration par défaut. Cela signifie que tous Par défaut, les apex sont aplatis, sauf si vous configurez explicitement votre appareil pour créer des APEX non aplatis afin de prendre en charge les mises à jour des APEX (comme expliqué ci-dessus).

Le mélange d'APEX aplatis et non aplatis dans un appareil n'est PAS compatibles. Les APEX d'un appareil doivent être tous non aplatis ou tous aplatis. C'est particulièrement important lorsque vous envoyez des APEX présignés tels que Mainline. Les apex qui ne sont pas présignés (c'est-à-dire construits à partir de la source) ne doivent pas non plus être aplatis et signés avec des clés appropriées. La l'appareil doit hériter de updatable_apex.mk, comme expliqué dans Mettre à jour un service avec un APEX

Apex compressés

Android 12 et versions ultérieures disposent de la compression APEX pour ce qui réduit l'impact sur le stockage des packages APEX pouvant être mis à jour. Après la mise à jour APEX est installé, bien que sa version préinstallée ne soit plus utilisée, occupe toujours le même espace. Cet espace occupé reste indisponible.

La compression APEX réduit cet impact de stockage en utilisant un ensemble hautement compressé des fichiers APEX sur des partitions en lecture seule (comme la partition /system). Android Les versions 12 et ultérieures utilisent un algorithme de compression ZIP DEFLATE.

La compression ne permet pas d'optimiser les éléments suivants:

  • Amorçage d’amorçage qui doivent être installés très tôt dans le démarrage séquence.

  • APEX non pouvant être mis à jour. La compression n'est utile que si une version mise à jour d'un APEX est installée sur la partition /data. La liste complète des APEX pouvant être mises à jour est disponible sur le Composants du système modulaires .

  • Apexes de bibliothèques partagées dynamiques. Étant donné que apexd active toujours les deux versions de de tels APEX (préinstallés et mis à niveau), la compression n’ajoute aucune valeur.

Format de fichier APEX compressé

Il s'agit du format d'un fichier APEX compressé.

Schéma illustrant le format d&#39;un fichier APEX compressé

Figure 2. Format de fichier APEX compressé

Le premier niveau est un fichier ZIP contenant l'original fichier apex déformé avec un niveau de compression de 9 et d'autres fichiers stockées non compressées.

Un fichier APEX comporte quatre fichiers:

  • original_apex: gonflé avec un niveau de compression de 9 Il s'agit du fichier APEX d'origine non compressé.
  • apex_manifest.pb: stocké uniquement
  • AndroidManifest.xml: stocké uniquement
  • apex_pubkey: stocké uniquement

Les fichiers apex_manifest.pb, AndroidManifest.xml et apex_pubkey sont des copies de leurs fichiers correspondants dans original_apex.

Créer un ApEX compressé

Les APEX compressés peuvent être créés à l'aide de l'outil apex_compression_tool.py situé à l'adresse system/apex/tools

Plusieurs paramètres liés à la compression APEX sont disponibles dans le système de compilation.

Dans Android.bp, le fait qu'un fichier APEX soit compressible est contrôlé par Propriété compressible:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

Un indicateur de produit PRODUCT_COMPRESSED_APEX détermine si une image système est compilée de la source doit contenir des fichiers APEX compressés.

Pour effectuer des tests en local, vous pouvez forcer une compilation à compresser les apex en définissant De OVERRIDE_PRODUCT_COMPRESSED_APEX= à true.

Les fichiers APEX compressés générés par le système de compilation portent l'extension .capex. Cette extension permet de faire plus facilement la distinction entre les fichiers compressés et non compressés. d'un fichier APEX.

Algorithmes de compression compatibles

Android 12 n'est compatible qu'avec la compression de fichiers avec décompression au format ZIP.

Activer un fichier APEX compressé au démarrage

Avant qu'un APEX compressé puisse être activé, le fichier original_apex qu'il contient est décompressé dans le répertoire /data/apex/decompressed. Le résultat le fichier APEX décompressé est lié au répertoire /data/apex/active.

Considérez l'exemple suivant comme une illustration du processus décrit ci-dessus.

Considérer /system/apex/com.android.foo.capex comme un APEX compressé est activé, avec le code de version 37.

  1. Le fichier original_apex dans /system/apex/com.android.foo.capex est décompressée en /data/apex/decompressed/com.android.foo@37.apex.
  2. restorecon /data/apex/decompressed/com.android.foo@37.apex est effectué pour vérifiez qu'il possède une étiquette SELinux correcte.
  3. Les vérifications sont effectuées sur /data/apex/decompressed/com.android.foo@37.apex pour garantir sa validité: apexd vérifie la clé publique intégrée /data/apex/decompressed/com.android.foo@37.apex pour vérifier que la valeur est égale par rapport à celui fourni dans /system/apex/com.android.foo.capex.
  4. Le fichier /data/apex/decompressed/com.android.foo@37.apex est lié à le répertoire /data/apex/active/com.android.foo@37.apex.
  5. La logique d'activation standard des fichiers APEX non compressés est effectuée sur /data/apex/active/com.android.foo@37.apex

Interaction avec l'agence de voyages en ligne

Les fichiers APEX compressés ont des conséquences sur la diffusion et l’application OTA. Depuis une mise à jour OTA peut contenir un fichier APEX compressé avec un niveau de version supérieur que ce qui est actif sur un appareil, vous devez réserver une certaine quantité d'espace libre avant de redémarrer un appareil pour appliquer une mise à jour OTA.

Pour prendre en charge le système OTA, apexd expose ces deux API de liaison:

  • calculateSizeForCompressedApex : calcule la taille requise pour la décompression Fichiers APEX dans un package OTA. Cela permet de vérifier qu'un appareil a d'espace de stockage suffisant avant le téléchargement d'une OTA.
  • reserveSpaceForCompressedApex : réserve de l'espace sur le disque pour une utilisation ultérieure. par apexd pour décompresser les fichiers APEX compressés dans le package OTA.

Dans le cas d'une mise à jour OTA A/B, apexd tente de décompresser le fichier en arrière-plan dans la routine OTA post-installation. Si la décompression échoue, apexd effectue la décompression pendant le démarrage qui applique l'OTA. mise à jour.

Alternatives envisagées lors du développement d'APEX

Voici quelques options prises en compte par l'AOSP lors de la conception du fichier APEX et pourquoi elles ont été incluses ou exclues.

Systèmes de gestion des paquets standards

Les distributions Linux ont des systèmes de gestion de paquets comme dpkg et rpm, puissants, matures et robustes. Cependant, ils n'étaient pas adopté pour APEX, car ils ne peuvent pas protéger les packages après l'installation. La vérification n'est effectuée que lors de l'installation des packages. Les attaquants peuvent briser l’intégrité des packages installés, inaperçus. C'est une régression pour Android où tous les composants du système étaient stockés en lecture seule des systèmes de fichiers dont l'intégrité est protégée par dm-verity pour chaque E/S. N'importe quelle valeur la falsification des composants du système doit être soit interdite, soit être détectable que l’appareil peut refuser de démarrer s’il est compromis.

dm-crypt pour l'intégrité

Les fichiers d'un conteneur APEX proviennent de partitions intégrées (par exemple, /system) protégées par dm-verity, où toute modification apportée à les fichiers sont interdits même après l'installation des partitions. Pour fournir le paramètre même niveau de sécurité pour les fichiers, tous les fichiers d'un APEX sont stockés dans un fichier une image système associée à une arborescence de hachage et à un descripteur vbmeta. Sans dm-verity, un APEX dans la partition /data est vulnérable aux risques les modifications apportées après avoir été vérifiée et installée.

En fait, la partition /data est également protégée par des couches de chiffrement telles que dm-crypt. Bien qu'elle offre un certain niveau de protection contre la falsification, l'objectif principal est la confidentialité et non l'intégrité. Lorsqu'un attaquant obtient l'accès /data, il ne peut pas y avoir de protection supplémentaire. Il s'agit là encore par rapport à chaque composant du système se trouvant dans la partition /system. L'arborescence de hachage dans un fichier APEX et dm-verity fournissent le même le niveau de protection du contenu.

Rediriger les chemins de /system vers /apex

Les fichiers des composants système empaquetés dans un APEX sont accessibles via de nouveaux chemins tels que /apex/<name>/lib/libfoo.so Date à laquelle les fichiers faisaient partie de /system , ils étaient accessibles via des chemins tels que /system/lib/libfoo.so. A client d'un fichier APEX (autres fichiers APEX ou la plate-forme) doit utiliser le nouveau chemins d'accès. Vous devrez peut-être mettre à jour le code existant à la suite du changement de chemin d'accès.

Bien qu'un moyen d'éviter le changement de chemin consiste à superposer le contenu du fichier dans une APEX sur la partition /system, l'équipe Android a décidé de ne pas superposer sur la partition /system, car cela pourrait affecter les performances lorsque le Nombre de fichiers superposés (éventuellement empilés les uns après les autres) a augmenté.

Une autre option consistait à pirater des fonctions d'accès aux fichiers telles que open, stat et readlink, de sorte que les chemins commençant par /system soient redirigés vers leur chemins correspondants sous /apex. L'équipe Android a supprimé cette option car il est impossible de modifier toutes les fonctions qui acceptent les chemins. Par exemple, certaines applications associent de manière statique Bionic, qui implémente les fonctions. Dans ce cas, ces applications ne sont pas redirigées.