Formato file APEX

Il formato contenitore Android Pony EXpress (APEX) è stato introdotto in Android 10 ed è utilizzato nel flusso di installazione per i moduli di sistema di livello inferiore. Questo formato facilita gli aggiornamenti dei componenti di sistema che non rientrano nel modello di applicazione Android standard. Alcuni componenti di esempio sono i servizi nativi e biblioteche, Hardware Abstraction Layer ( HAL ), runtime ( ART ), e librerie di classi.

Il termine "APEX" può anche riferirsi a un file APEX.

Sfondo

Sebbene Android supporti gli aggiornamenti dei moduli che rientrano nel modello di app standard (ad esempio, servizi, attività) tramite app di installazione di pacchetti (come l'app Google Play Store), l'utilizzo di un modello simile per i componenti del sistema operativo di livello inferiore presenta i seguenti inconvenienti:

  • I moduli basati su APK non possono essere usati all'inizio della sequenza di avvio. Il gestore dei pacchetti è il repository centrale delle informazioni sulle app e può essere avviato solo dal gestore delle attività, che diventa pronto in una fase successiva della procedura di avvio.
  • Il formato APK (in particolare il manifest) è progettato per le app Android e i moduli di sistema non sono sempre adatti.

Design

Questa sezione descrive la progettazione di alto livello del formato file APEX e APEX manager, che è un servizio che gestisce i file APEX.

Per ulteriori informazioni sul motivo per cui è stato scelto questo disegno per APEX, vedere alternative considerate nello sviluppo APEX .

Formato APEX

Questo è il formato di un file APEX.

Formato file APEX

Formato di file Figura 1. APEX

Al livello più alto, un file APEX è un file zip in cui i file sono archiviati non compressi e situati a limiti di 4 KB.

I quattro file in un file APEX sono:

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

apex_manifest.json file contiene il nome del pacchetto e la versione, che identificano un file APEX.

AndroidManifest.xml file consente il file APEX di utilizzare strumenti APK e le infrastrutture connesse, come ADB, PackageManager, e applicazioni di installazione del pacchetto (come Play Store). Ad esempio, il file APEX può utilizzare uno strumento esistente come aapt per ispezionare i metadati di base dal file. Il file contiene il nome del pacchetto e le informazioni sulla versione. Questa informazione è generalmente disponibile anche in apex_manifest.json .

apex_manifest.json è raccomandato nel corso AndroidManifest.xml per il nuovo codice e sistemi che si occupano di APEX. AndroidManifest.xml potrebbe contenere le informazioni di targeting aggiuntivo che può essere utilizzato dagli strumenti di pubblicazione di app esistenti.

apex_payload.img è l'immagine del file system ext4 sostenuta da dm-Verity. L'immagine viene montata in fase di esecuzione tramite un dispositivo di loopback. In particolare, l'albero di hash e il blocco di metadati vengono creati utilizzando il libavb biblioteca. Il payload del file system non viene analizzato (perché l'immagine dovrebbe essere montabile sul posto). File regolari sono compresi all'interno del apex_payload.img file.

apex_pubkey è la chiave pubblica utilizzata per firmare l'immagine del file system. In fase di esecuzione, questa chiave garantisce che l'APEX scaricato sia firmato con la stessa entità che firma lo stesso APEX nelle partizioni integrate.

APEX manager

Il manager APEX (o apexd ) è un processo nativo autonomo responsabile della verifica, l'installazione e la disinstallazione dei file APEX. Questo processo viene avviato ed è pronto all'inizio della sequenza di avvio. File APEX sono normalmente pre-installato sul dispositivo in /system/apex . Il gestore APEX utilizza per impostazione predefinita questi pacchetti se non sono disponibili aggiornamenti.

La sequenza di aggiornamento di un APEX utilizza la classe PackageManager ed è il seguente.

  1. Un file APEX viene scaricato tramite un'app di installazione del pacchetto, ADB o un'altra fonte.
  2. Il gestore dei pacchetti avvia la procedura di installazione. Dopo aver riconosciuto che il file è un APEX, il gestore pacchetti trasferisce il controllo al gestore APEX.
  3. Il gestore APEX verifica il file APEX.
  4. Se il file APEX è verificato, il database interno del gestore APEX viene aggiornato per indicare che il file APEX viene attivato all'avvio successivo.
  5. Il richiedente dell'installazione riceve una trasmissione dopo la verifica del pacchetto riuscita.
  6. Per continuare l'installazione, è necessario riavviare il sistema.
  7. All'avvio successivo, il gestore APEX si avvia, legge il database interno ed esegue le seguenti operazioni per ciascun file APEX elencato:

    1. Verifica il file APEX.
    2. Crea un dispositivo di loopback dal file APEX.
    3. Crea un dispositivo a blocchi del mappatore del dispositivo sopra il dispositivo di loopback.
    4. Monta il dispositivo di blocco dispositivo mappatore su un percorso univoco (ad esempio, /apex/ name @ ver ).

Quando tutti i file APEX elencati nel database interno sono montati, il gestore APEX fornisce un servizio di associazione per altri componenti del sistema per richiedere informazioni sui file APEX installati. Ad esempio, gli altri componenti del sistema possono interrogare l'elenco dei file APEX installati nel dispositivo o interrogare il percorso esatto in cui è montato un APEX specifico, in modo da poter accedere ai file.

I file APEX sono file APK

File APEX sono file APK validi perché sono firmate archivi ZIP (utilizzando lo schema di firma APK) contenente un AndroidManifest.xml file. Ciò consente ai file APEX di utilizzare l'infrastruttura per i file APK, ad esempio un'app di installazione del pacchetto, l'utilità di firma e il gestore pacchetti.

AndroidManifest.xml file all'interno di un file di APEX è minimo, costituito dal pacchetto di name , versionCode , e facoltativo targetSdkVersion , minSdkVersion e maxSdkVersion per grana fine targeting. Queste informazioni consentono di distribuire i file APEX tramite canali esistenti come app di installazione di pacchetti e ADB.

Tipi di file supportati

Il formato APEX supporta questi tipi di file:

  • Librerie condivise native
  • Eseguibili nativi
  • File JAR
  • File di dati
  • File di configurazione

Ciò non significa che APEX possa aggiornare tutti questi tipi di file. La possibilità di aggiornare un tipo di file dipende dalla piattaforma e dalla stabilità delle definizioni delle interfacce per i tipi di file.

firma

I file APEX sono firmati in due modi. In primo luogo, apex_payload.img (in particolare, il descrittore vbmeta allegata al apex_payload.img ) file è firmato con una chiave. Poi, l'intero APEX è firmato con il v3 APK schema di firma . In questo processo vengono utilizzate due chiavi diverse.

Sul lato dispositivo è installata una chiave pubblica corrispondente alla chiave privata utilizzata per firmare il descrittore vbmeta. Il gestore APEX utilizza la chiave pubblica per verificare gli APEX di cui è richiesta l'installazione. Ogni APEX deve essere firmato con chiavi diverse e viene applicato sia in fase di compilazione che in fase di esecuzione.

APEX nelle partizioni integrate

File APEX possono essere ubicati in built-in partizioni come il /system . La partizione è già su dm-verity, quindi i file APEX vengono montati direttamente sul dispositivo di loopback.

Se un APEX è presente in una partizione incorporata, l'APEX può essere aggiornato fornendo un pacchetto APEX con lo stesso nome del pacchetto e un codice di versione maggiore o uguale. Il nuovo APEX è memorizzato in /data e, simile a APKs, la versione ombre appena installato la versione già presenti nella partizione built-in. Ma a differenza degli APK, la versione appena installata dell'APEX viene attivata solo dopo il riavvio.

Requisiti del kernel

Per supportare i moduli mainline APEX su un dispositivo Android, sono necessarie le seguenti funzionalità del kernel Linux: il driver di loopback e dm-verity. Il driver loopback monta l'immagine del file system in un modulo APEX e dm-verity verifica il modulo APEX.

Le prestazioni del driver di loopback e di dm-verity sono importanti per ottenere buone prestazioni di sistema quando si utilizzano i moduli APEX.

Versioni del kernel supportate

I moduli principali di APEX sono supportati sui dispositivi che utilizzano le versioni del kernel 4.4 o successive. I nuovi dispositivi avviati con Android 10 o versioni successive devono utilizzare la versione del kernel 4.9 o successiva per supportare i moduli APEX.

Patch del kernel richieste

Le patch del kernel richieste per supportare i moduli APEX sono incluse nell'albero comune di Android. Per fare in modo che le patch supportino APEX, utilizza l'ultima versione dell'albero comune di Android.

Versione del kernel 4.4

Questa versione è supportata solo per i dispositivi aggiornati da Android 9 ad Android 10 e che desiderano supportare i moduli APEX. Per ottenere le patch richieste, un down-merge dal android-4.4 filiale è fortemente raccomandato. Di seguito è riportato un elenco delle singole patch richieste per la versione del kernel 4.4.

  • A MONTE: ciclo: aggiungere ioctl per cambiare la dimensione dei blocchi logici ( 4.4 )
  • Backport: blocco / loop: set hw_sectors ( 4.4 )
  • A MONTE: ciclo: Add LOOP_SET_BLOCK_SIZE in compat ioctl ( 4.4 )
  • ANDROID: mnt: Fix next_descendent ( 4.4 )
  • ANDROID: mnt: rimontare dovrebbe propagarsi agli schiavi di schiavi ( 4.4 )
  • ANDROID: mnt: Propagate rimontare correttamente ( 4.4 )
  • Revert "ANDROID: dm Verity: aggiungere dimensione minima di precaricamento" ( 4.4 )
  • A MONTE: ciclo: cache goccia Se offset o BLOCK_SIZE sono cambiati ( 4.4 )

Versioni del kernel 4.9/4.14/4.19

Per ottenere le patch necessarie per le versioni del kernel 4.9 / 4.14 / 4.19, down-merge dal android-common ramo.

Opzioni di configurazione del kernel richieste

L'elenco seguente mostra i requisiti di configurazione di base per supportare i moduli APEX introdotti in Android 10. Gli elementi con un asterisco (*) sono requisiti esistenti da Android 9 e versioni precedenti.

(*) 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

Requisiti dei parametri della riga di comando del kernel

Per supportare APEX, assicurati che i parametri della riga di comando del kernel soddisfino i seguenti requisiti:

  • loop.max_loop non deve essere impostato
  • loop.max_part deve essere <= 8

Costruire un APEX

Questa sezione descrive come creare un APEX utilizzando il sistema di build Android. Quanto segue è un esempio di Android.bp per un apice di nome 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",
}

apex_manifest.json Esempio:

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

file_contexts Esempio:

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

Tipi di file e posizioni in APEX

Tipo di file Posizione in APEX
Librerie condivise /lib e /lib64 ( /lib/arm per braccio tradotto in 86)
eseguibili /bin
Librerie Java /javalib
Precostruiti /etc

Dipendenze transitive

I file APEX includono automaticamente le dipendenze transitive di librerie o eseguibili condivisi nativi. Per esempio, se libFoo dipende libBar , le due librerie sono incluse in cui solo libFoo è elencata nella native_shared_libs proprietà.

Gestione di più ABI

Installare il native_shared_libs struttura per entrambe le interfacce applicazione binarie primarie e secondarie (ABI) del dispositivo. Se un APEX punta a dispositivi con un'unica ABI (ovvero solo a 32 bit o solo a 64 bit), vengono installate solo le librerie con l'ABI corrispondente.

Installare binaries proprietà solo per il primario ABI del dispositivo come descritto di seguito:

  • Se il dispositivo è solo a 32 bit, viene installata solo la variante a 32 bit del binario.
  • Se il dispositivo è solo a 64 bit, viene installata solo la variante a 64 bit del binario.

Per aggiungere il controllo a grana fine nel corso degli ABI delle librerie e binari nativi, utilizzare il multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] proprietà.

  • first : Corrisponde primario ABI del dispositivo. Questa è l'impostazione predefinita per i binari.
  • lib32 : Corrisponde 32 bit ABI del dispositivo, se supportato.
  • lib64 : Corrisponde a 64 bit ABI del dispositivo, esso supportato.
  • prefer32 : Corrisponde 32 bit ABI del dispositivo, se supportato. Se l'ABI a 32 bit non è supportato, corrisponde all'ABI a 64 bit.
  • both : corrisponde sia ABI. Questa è l'impostazione predefinita per native_shared_libraries .

I java , libraries , e prebuilts proprietà sono ABI-agnostico.

Questo esempio è per un dispositivo che supporta 32/64 e non preferisce 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
        },
    },
}

vbmeta firma

Firma ogni APEX con chiavi diverse. Quando è richiesta una nuova chiave, creare una coppia di chiavi pubblica-privata e fare un apex_key modulo. Utilizzare la key di proprietà per firmare l'APEX con il tasto. La chiave pubblica viene automaticamente inclusa nel APEX con il nome 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",
}

Nell'esempio di cui sopra, il nome della chiave pubblica ( foo ) diventa l'ID della chiave. L'ID della chiave utilizzata per firmare un APEX è scritto nell'APEX. In fase di esecuzione, apexd verifica l'APEX utilizzando una chiave pubblica con lo stesso ID nel dispositivo.

Firma ZIP

Firma gli APEX nello stesso modo in cui firmi gli APK. Firma APEX due volte; una volta per il mini sistema di file ( apex_payload.img file) e una volta per l'intero file.

Per firmare un APEX a livello di file, impostare il certificate proprietà in uno di questi tre modi:

  • Non impostato: Se nessun valore è impostato, l'apice è firmato con il certificato situato a PRODUCT_DEFAULT_DEV_CERTIFICATE . Se nessun flag è impostato, le impostazioni predefinite di percorso per build/target/product/security/testkey .
  • <name> : l'apice è firmato con il <name> certificato nella stessa directory PRODUCT_DEFAULT_DEV_CERTIFICATE .
  • :<name> : l'apice è firmato con il certificato che viene definita dal modulo Soong denominata <name> . Il modulo del certificato può essere definito come segue.
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)
}

Installazione di un APEX

Per installare un APEX, usa ADB.

adb install apex_file_name
adb reboot

Utilizzo di un APEX

Dopo il riavvio, l'apice è montato sul /apex/<apex_name>@<version> directory. È possibile montare più versioni dello stesso APEX contemporaneamente. Tra i percorsi di montaggio, quella che corrisponde alla versione più recente è bind-montato /apex/<apex_name> .

I client possono utilizzare il percorso montato su bind per leggere o eseguire file da APEX.

Gli APEX vengono generalmente utilizzati come segue:

  1. Un ODM o precarichi un apice in /system/apex quando il dispositivo viene spedito.
  2. I file nella APEX sono accessibili tramite il /apex/<apex_name>/ percorso.
  3. Quando una versione aggiornata della APEX è installato in /data/apex , i punti di percorso per la nuova APEX dopo il riavvio.

Aggiornamento di un servizio con un APEX

Per aggiornare un servizio utilizzando un APEX:

  1. Contrassegna il servizio nella partizione di sistema come aggiornabile. Aggiungere l'opzione updatable alla definizione di servizio.

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. Creare un nuovo .rc file per il servizio aggiornato. Utilizzare l' override opzione per ridefinire il servizio esistente.

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

Definizioni di servizio possono essere definiti solo nella .rc file di un APEX. I trigger di azione non sono supportati negli APEX.

Se un servizio contrassegnato come aggiornabile viene avviato prima dell'attivazione degli APEX, l'avvio viene ritardato fino al completamento dell'attivazione degli APEX.

Configurazione del sistema per supportare gli aggiornamenti APEX

Impostare la seguente proprietà di sistema per true per supportare gli aggiornamenti dei file APEX.

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

o semplicemente

<device.mk>:

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

APEX appiattito

Per i dispositivi legacy, a volte è impossibile o impossibile aggiornare il vecchio kernel per supportare completamente APEX. Ad esempio, il kernel potrebbe essere stato costruito senza CONFIG_BLK_DEV_LOOP=Y , che è cruciale per il montaggio del sistema di file immagine all'interno di un apice.

L'APEX appiattito è un APEX appositamente creato che può essere attivato su dispositivi con un kernel legacy. I file in un APEX appiattito vengono installati direttamente in una directory nella partizione incorporata. Ad esempio, lib/libFoo.so in una appiattita APEX my.apex è installato a /system/apex/my.apex/lib/libFoo.so .

L'attivazione di un APEX appiattito non coinvolge il dispositivo loop. L'intera directory /system/apex/my.apex è direttamente bind-montato /apex/name@ver .

Gli APEX appiattiti non possono essere aggiornati scaricando versioni aggiornate degli APEX dalla rete perché gli APEX scaricati non possono essere appiattiti. Gli APEX appiattiti possono essere aggiornati solo tramite una normale OTA.

APEX appiattito è la configurazione predefinita. Ciò significa che tutti gli APEX sono appiattiti per impostazione predefinita a meno che non si configuri esplicitamente il dispositivo per creare APEX non appiattiti per supportare gli aggiornamenti APEX (come spiegato sopra).

La combinazione di APEX appiattiti e non appiattiti in un dispositivo NON è supportata. Gli APEX in un dispositivo devono essere tutti non appiattiti o tutti appiattiti. Ciò è particolarmente importante quando si spediscono precompilati APEX pre-firmati per progetti come Mainline. Anche gli APEX che non sono prefirmati (ovvero compilati dal sorgente) dovrebbero essere non appiattiti e firmati con le chiavi appropriate. Il dispositivo dovrebbe ereditare da updatable_apex.mk come spiegato in Aggiornamento di un servizio con un apice .

APEX compressi

Android 12 e versioni successive dispongono della compressione APEX per ridurre l'impatto sull'archiviazione dei pacchetti APEX aggiornabili. Dopo l'installazione di un aggiornamento a un APEX, sebbene la sua versione preinstallata non venga più utilizzata, occupa ancora la stessa quantità di spazio. Quello spazio occupato rimane non disponibile.

Compressione APEX riduce al minimo questo impatto di archiviazione utilizzando un insieme altamente compresso di file APEX sulle partizioni di sola lettura (come ad esempio il /system partizione). Android 12 e versioni successive utilizzano un algoritmo di compressione zip DEFLATE.

La compressione non fornisce l'ottimizzazione a quanto segue:

  • Bootstrap APEX che devono essere montati molto presto nella sequenza di avvio.

  • APEX non aggiornabili. La compressione è utile solo se è installata una versione aggiornata di un APEX sul /data della partizione. Un elenco completo dei vertici aggiornabili è disponibile sul modulare componenti del sistema pagina.

  • APEX di librerie condivise dinamiche. Dal momento che apexd attiva sempre entrambe le versioni di tali apici (pre-installato e aggiornato), comprimendo loro non aggiungono valore.

Formato file compresso APEX

Questo è il formato di un file APEX compresso.

Diagram shows the format of a compressed APEX file

Formato figura 2. compresso APEX

Al livello più alto, un file APEX compresso è un file zip contenente il file apex originale in forma sgonfia con un livello di compressione di 9 e con altri file archiviati non compressi.

Quattro file comprendono un file APEX:

  • original_apex : sgonfiato con il livello di compressione del 9 Questo è l'originale, non compresso di file APEX .
  • apex_manifest.pb : solo memorizzata
  • AndroidManifest.xml : immagazzinato solo
  • apex_pubkey : solo memorizzata

apex_manifest.pb , AndroidManifest.xml e apex_pubkey file sono copie dei loro file corrispondenti a original_apex .

Costruire APEX compresso

Compresso APEX può essere costruito utilizzando apex_compression_tool.py utensile situata system/apex/tools .

Diversi parametri relativi alla compressione APEX sono disponibili nel sistema di compilazione.

In Android.bp se un file di APEX è comprimibile è controllata dal compressible immobile:

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

Un PRODUCT_COMPRESSED_APEX controlli bandiera prodotto se un'immagine del sistema installato dal codice sorgente devono contengono file compressi APEX.

Per sperimentazione locale è possibile forzare una build per apici comprimere impostando OVERRIDE_PRODUCT_COMPRESSED_APEX= a true .

Compressed APEX file generati dal sistema di compilazione ha la .capex estensione. L'estensione semplifica la distinzione tra versioni compresse e non compresse di un file APEX.

Algoritmi di compressione supportati

Android 12 supporta solo la compressione deflate-zip.

Attivazione di un file APEX compresso durante l'avvio

Prima che un APEX compressa può essere attivato, original_apex file all'interno di è decompresso in /data/apex/decompressed directory. Il file decompresso APEX risultante è difficile legato alla /data/apex/active directory.

Considera il seguente esempio come illustrazione del processo descritto sopra.

Considerare /system/apex/com.android.foo.capex come APEX compressa essendo attivata, con versionCode 37.

  1. original_apex file all'interno di /system/apex/com.android.foo.capex viene decompresso in /data/apex/decompressed/com.android.foo@37.apex .
  2. restorecon /data/apex/decompressed/com.android.foo@37.apex viene eseguito per verificare che abbia un'etichetta SELinux corretta.
  3. Verifica i controlli vengono eseguiti su /data/apex/decompressed/com.android.foo@37.apex per assicurare la sua validità: apexd controlli la chiave pubblica in bundle /data/apex/decompressed/com.android.foo@37.apex a verificare che è uguale a quello impacchettato in /system/apex/com.android.foo.capex .
  4. Il /data/apex/decompressed/com.android.foo@37.apex file è difficile legato alla /data/apex/active/com.android.foo@37.apex directory.
  5. La logica normale di attivazione per i file non compressi APEX viene eseguita su /data/apex/active/com.android.foo@37.apex .

Interazione con OTA

I file APEX compressi hanno implicazioni sulla consegna e l'applicazione di OTA. Poiché un aggiornamento OTA potrebbe contenere un file APEX compresso con un livello di versione superiore rispetto a quello attivo su un dispositivo, è necessario riservare una certa quantità di spazio libero prima di riavviare un dispositivo per applicare un aggiornamento OTA.

Per supportare il sistema OTA, apexd espone queste due API leganti:

  • calculateSizeForCompressedApex - calcola le dimensioni necessarie per i file APEX decomprimere in un pacchetto OTA. Questo può essere utilizzato per verificare che un dispositivo disponga di spazio sufficiente prima che venga scaricata un'OTA.
  • reserveSpaceForCompressedApex - riserve di spazio sul disco per un uso futuro apexd per decomprimere i file compressi APEX all'interno del pacchetto OTA.

Nel caso di un aggiornamento A / B OTA, apexd tentativi di decompressione in background come parte del postinstall OTA routine. Se decompressione fallisce, apexd esegue la decompressione durante l'avvio che applica l'aggiornamento OTA.

Alternative considerate durante lo sviluppo di APEX

Ecco alcune opzioni prese in considerazione da AOSP durante la progettazione del formato di file APEX e il motivo per cui sono state incluse o escluse.

Sistemi di gestione dei pacchi regolari

Distribuzioni di Linux hanno sistemi di gestione dei pacchetti come dpkg e rpm , che sono potenti, maturare, e robusto. Tuttavia, non sono stati adottati per APEX perché non possono proteggere i pacchetti dopo l'installazione. La verifica viene eseguita solo durante l'installazione dei pacchetti. Gli aggressori possono violare l'integrità dei pacchetti installati, senza essere notati. Questa è una regressione per Android in cui tutti i componenti del sistema sono stati archiviati in file system di sola lettura la cui integrità è protetta da dm-verity per ogni I/O. Qualsiasi manomissione dei componenti del sistema deve essere vietata o essere rilevabile in modo che il dispositivo possa rifiutarsi di avviarsi se compromesso.

dm-crypt per l'integrità

I file in un contenitore APEX sono da built-in partizioni (ad esempio, il /system partizione) che sono protetti dal dm-Verity, in cui ogni modifica ai file sono vietati anche dopo che le partizioni sono montate. Per fornire lo stesso livello di sicurezza ai file, tutti i file in un APEX sono archiviati in un'immagine del file system che è accoppiata con un albero hash e un descrittore vbmeta. Senza dm-verità, un apice nel /data della partizione è vulnerabile alle modifiche non intenzionali che sono fatti dopo che è stato verificato e installato.

In realtà, il /data della partizione è inoltre protetto da strati di crittografia quali dm-crypt. Sebbene ciò fornisca un certo livello di protezione contro la manomissione, il suo scopo principale è la privacy, non l'integrità. Quando un malintenzionato accede al /data della partizione, non ci può essere alcuna ulteriore protezione, e questo ancora una volta è una regressione rispetto ad ogni componente del sistema essendo in /system partizione. L'albero hash all'interno di un file APEX insieme a dm-verity fornisce lo stesso livello di protezione del contenuto.

Reindirizzamento dei percorsi da /system a /apex

File dei componenti di sistema confezionati in un apice sono accessibili tramite nuovi percorsi come /apex/<name>/lib/libfoo.so . Quando i file sono stati parte del /system partizione, erano accessibili tramite percorsi come /system/lib/libfoo.so . Un client di un file APEX (altri file APEX o la piattaforma) deve utilizzare i nuovi percorsi. Potrebbe essere necessario aggiornare il codice esistente in seguito alla modifica del percorso.

Anche se un modo per evitare la modifica del percorso è quello di sovrapporre il contenuto del file in un file di APEX sul /system partizione, il team di Android ha deciso di non file overlay sul /system partizione, perché questo potrebbe influire sulle prestazioni come il numero di file che vengono sovrapposto ( possibilmente anche impilati uno dopo l'altro) sono aumentati.

Un'altra opzione era dirottare le funzioni di accesso ai file come open , stat , e readlink , in modo che i percorsi che iniziano con /system sono stati reindirizzati loro percorsi corrispondenti sotto /apex . Il team di Android ha scartato questa opzione perché non è possibile modificare tutte le funzioni che accettano percorsi. Ad esempio, alcune app collegano staticamente Bionic, che implementa le funzioni. In questi casi, quelle app non vengono reindirizzate.