Il formato del contenitore Android Pony EXpress (APEX) è stato introdotto in Android 10 e viene utilizzato nel flusso di installazione per i sistemi di livello inferiore moduli. Questo formato facilita l'aggiornamento dei componenti di sistema nel modello di app Android standard. Alcuni componenti di esempio sono nativi servizi e librerie, livelli di astrazione hardware (HAL), runtime (ART) e librerie di classi.
Il termine "APEX" può anche fare riferimento a un file APEX.
Premessa
Sebbene Android supporti gli aggiornamenti dei moduli che si adattano all'app standard modello (ad esempio servizi, attività) tramite le app di installazione di pacchetti (come l'app Google Play Store), utilizzando un modello simile per i componenti di livello inferiore del sistema operativo presenta i seguenti svantaggi:
- I moduli basati su APK non possono essere utilizzati all'inizio della sequenza di avvio. Il pacchetto è il repository centrale di informazioni sulle app e può essere da Gestione attività, che diventa pronto in una fase successiva la procedura di avvio.
- Il formato APK (in particolare il file manifest) è progettato per le app Android e i moduli di sistema non sempre sono adatti.
Design
Questa sezione descrive la progettazione di alto livello del formato file APEX e la APEX Manager, un servizio che gestisce i file APEX.
Per ulteriori informazioni sul motivo per cui è stata selezionata questa struttura per APEX, vedi Le alternative prese in considerazione durante lo sviluppo di APEX.
Formato APEX
Questo è il formato di un file APEX.
Figura 1. Formato file APEX
Al livello principale, un file APEX è un file ZIP in cui vengono archiviati i file non compresso e posizionato a limiti di 4 kB.
I quattro file di un file APEX sono:
apex_manifest.json
AndroidManifest.xml
apex_payload.img
apex_pubkey
Il file apex_manifest.json
contiene il nome e la versione del pacchetto,
identificare un file APEX. Si tratta di un
ApexManifest
di protocollo in formato JSON.
Il file AndroidManifest.xml
consente al file APEX di utilizzare strumenti e strumenti relativi agli APK
dell'infrastruttura come ADB, PackageManager e le app di installazione dei pacchetti (come
Play Store). Ad esempio, il file APEX può utilizzare uno strumento esistente come aapt
per esaminare i metadati di base del file. Il file contiene il nome del pacchetto e
le informazioni sulla versione. Queste informazioni sono generalmente disponibili anche in
apex_manifest.json
.
L'importo consigliato di apex_manifest.json
è superiore a AndroidManifest.xml
per il nuovo codice e
sistemi che si occupano di APEX. AndroidManifest.xml
potrebbe contenere elementi
informazioni sul targeting che possono essere utilizzate dagli strumenti di pubblicazione delle app esistenti.
apex_payload.img
è un'immagine di file system ext4 supportata da dm-verity. L'immagine
è montato in fase di runtime tramite un dispositivo di loopback. Nello specifico, l'albero di hash e
vengono creati utilizzando la libreria libavb
. Payload del file system
non viene analizzato (perché l'immagine deve essere montabile in posizione). I file normali sono
incluso all'interno del file apex_payload.img
.
apex_pubkey
è la chiave pubblica utilizzata per firmare l'immagine del file system. In fase di runtime,
questa chiave garantisce che l'APEX scaricato sia firmato con la stessa entità
che firma lo stesso APEX nelle partizioni integrate.
Linee guida per la denominazione APEX
Per evitare conflitti di denominazione tra i nuovi APEX con i progressi della piattaforma, segui queste linee guida per l'assegnazione dei nomi:
com.android.*
- Riservato per AOSP APEX. Non univoco per alcuna azienda o dispositivo.
com.<companyname>.*
- Riservato a un'azienda. Potenzialmente usato da più dispositivi da quella dell'azienda.
com.<companyname>.<devicename>.*
- Riservato per gli APEX univoci per un dispositivo specifico (o un sottoinsieme di dispositivi).
Gestore APEX
Il gestore APEX (o apexd
) è un processo nativo autonomo responsabile
verificare, installare e disinstallare i file APEX. Questo processo viene avviato
sia pronto all'inizio della sequenza di avvio. I file APEX sono in genere preinstallati su
del dispositivo in /system/apex
. Per impostazione predefinita, il gestore APEX utilizza questi
di pacchetti se non sono disponibili aggiornamenti.
La sequenza di aggiornamento di un APEX utilizza Classe PackageManager ed è il seguente.
- Un file APEX viene scaricato tramite un'app di installazione di pacchetti, ADB o un altro sorgente.
- Il gestore di pacchetti avvia la procedura di installazione. Dopo aver capito che il file è un APEX, il gestore dei pacchetti trasferisce il controllo all'APEX responsabile.
- Il gestore APEX verifica il file APEX.
- Se il file APEX è verificato, il database interno del gestore APEX viene aggiornato in modo da indicare che il file APEX viene attivato all'avvio successivo.
- Il richiedente dell'installazione riceve un annuncio quando il pacchetto è riuscito verifica.
- Per continuare l'installazione è necessario riavviare il sistema.
All'avvio successivo, il gestore APEX si avvia, legge il database interno quanto segue per ogni file APEX elencato:
- Verifica il file APEX.
- Crea un dispositivo di loopback dal file APEX.
- Crea un dispositivo di blocco device Mapper sopra il dispositivo di loopback.
- Monta il dispositivo a blocchi Device Mapper su un percorso univoco (ad esempio,
/apex/name@ver
).
Quando tutti i file APEX elencati nel database interno sono montati, l'APEX fornisce un servizio di legatura per consentire ad altri componenti del sistema di eseguire query informazioni sui file APEX installati. Ad esempio, l'altro sistema componenti possono interrogare l'elenco dei file APEX installati sul dispositivo o interrogare percorso esatto in cui è montato un APEX specifico, in modo che sia possibile accedere ai file.
I file APEX sono file APK
I file APEX sono file APK validi perché sono archivi ZIP firmati (utilizzando i file
schema di firma APK) contenente un file AndroidManifest.xml
. Ciò consente ad APEX
per utilizzare l'infrastruttura dei file APK, ad esempio un'app di installazione di pacchetti,
l'utilità di firma e il gestore di pacchetti.
Il file AndroidManifest.xml
all'interno di un file APEX è minimo ed è composto da
pacchetto name
, versionCode
e targetSdkVersion
, minSdkVersion
facoltativo,
e maxSdkVersion
per un targeting granulare. Queste informazioni consentono ad APEX
di file da distribuire tramite canali esistenti, come le app di installazione di pacchetti e
ADB.
Tipi di file supportati
Il formato APEX supporta i seguenti tipi di file:
- Libreria condivisa nativa
- Eseguibili nativi
- File JAR
- File di dati
- File di configurazione
Ciò non significa che APEX può aggiornare tutti questi tipi di file. Indica se un file tipo può essere aggiornato dipende dalla piattaforma e dalla stabilità delle definizioni le interfacce per i tipi di file.
Opzioni di firma
I file APEX vengono firmati in due modi diversi. Innanzitutto, apex_payload.img
(nello specifico,
il descrittore vbmeta aggiunto al file apex_payload.img
) è firmato con una chiave.
Quindi, l'intero APEX viene firmato utilizzando
Schema di firma dell'APK v3. Vengono utilizzate due chiavi diverse
in questo processo.
Sul lato dispositivo, una chiave pubblica corrispondente alla chiave privata utilizzata per la firma. il descrittore vbmeta sia installato. Il gestore APEX utilizza la chiave pubblica per verificare gli APEX di cui è richiesta l'installazione. Ogni APEX deve essere firmato con diverse chiavi e viene applicata sia in fase di build che in fase di runtime.
APEX nelle partizioni integrate
I file APEX possono trovarsi in partizioni integrate come /system
. La
la partizione è già su dm-verity, quindi i file APEX vengono montati direttamente
tramite il dispositivo di loopback.
Se un APEX è presente in una partizione integrata, l'APEX può essere aggiornato
fornendo un pacchetto APEX con lo stesso nome di pacchetto e un numero maggiore o uguale
al codice di versione. Il nuovo APEX viene memorizzato in /data
e, come per gli APK, nella
la versione appena installata mette in ombra la versione già presente nel
della partizione di testo. Ma a differenza degli APK, la versione appena installata dell'APEX viene
attivata dopo il riavvio.
Requisiti del kernel
Per supportare i moduli APEX mainline su un dispositivo Android, le seguenti versioni le funzionalità kernel sono obbligatorie: il driver di loopback e dm-verity. Il loopback il driver monta l'immagine del file system in un modulo APEX e dm-verity verifica Modulo APEX.
Le prestazioni del driver di loopback e della dm-verity sono importanti per ottenere buone prestazioni di sistema con i moduli APEX.
Versioni kernel supportate
I moduli APEX mainline sono supportati su dispositivi che utilizzano le versioni del kernel 4.4 o in alto. Lancio di nuovi dispositivi con Android 10 o versioni successive deve usare il kernel versione 4.9 o successiva per supportare i moduli APEX.
Patch del kernel richieste
Le patch del kernel richieste per il supporto dei moduli APEX sono incluse nel Albero comune di Android. Per far sì che le patch supportino APEX, usa la versione più recente dell'albero comune di Android.
Kernel versione 4.4
Questa versione è supportata solo per i dispositivi di cui viene eseguito l'upgrade da Android 9 ad
Android 10 e vogliono supportare i moduli APEX. Per ottenere
le patch richieste, un'unione dinamica dal ramo android-4.4
è fortemente
consigliato. Di seguito è riportato un elenco delle singole patch richieste
per kernel versione 4.4.
- UPSTREAM: loop: aggiungi ioctl per modificare la dimensione del blocco logico (4,4)
- BACKPORT: block/loop: imposta hw_sectors (4,4)
- UPSTREAM: loop: aggiungi LOOP_SET_BLOCK_SIZE in ioctl (4,4)
- ANDROID: mnt: Correggi next_descendent (4,4)
- ANDROID: mnt: la rimonta dovrebbe propagarsi agli schiavi. (4,4)
- ANDROID: mnt: Propaga e rimonta correttamente (4,4)
- Ripristina "ANDROID: dm verity: aggiungi dimensione minima di precaricamento" (4,4)
- UPSTREAM: loop: elimina le cache se vengono modificati gli offset o le dimensioni block_size (4,4)
Versioni del kernel 4.9/4.14/4.19
Per ottenere le patch richieste per le versioni del kernel 4.9/4.14/4.19, down-merge
nel ramo android-common
.
Opzioni di configurazione kernel richieste
Il seguente elenco mostra i requisiti di configurazione di base per il supporto Moduli APEX introdotti in Android 10. Gli elementi contrassegnati con un asterisco (*) sono i requisiti esistenti di 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 requisiti:
loop.max_loop
NON deve essere impostatoloop.max_part
deve essere <= 8
Crea un APEX
Questa sezione descrive come creare un APEX usando il sistema di compilazione Android.
Di seguito è riportato un esempio di Android.bp
per un APEX denominato 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",
}
Esempio di apex_manifest.json
:
{
"name": "com.android.example.apex",
"version": 1
}
Esempio di file_contexts
:
(/.*)? 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 | Località in APEX |
---|---|
Raccolte condivise | /lib e /lib64 (/lib/arm per
gruppo tradotto in x86) |
Eseguibili | /bin |
Librerie Java | /javalib |
Predefiniti | /etc |
Dipendenze transitive
I file APEX includono automaticamente le dipendenze transitive delle librerie condivise native
o eseguibili. Ad esempio, se libFoo
dipende da libBar
, le due librerie vengono
incluso quando solo libFoo
è elencato nella proprietà native_shared_libs
.
Gestire più ABI
Installa la proprietà native_shared_libs
sia per l'account principale che per quello secondario
applicazioni binarie dell'applicazione (ABI) del dispositivo. Se un APEX ha come target i dispositivi
con una singola ABI (ovvero solo a 32 bit o solo a 64 bit), solo le librerie con
sia installata l'ABI corrispondente.
Installa la proprietà binaries
solo per l'ABI principale del dispositivo come
descritti di seguito:
- Se il dispositivo è solo a 32 bit, solo la variante a 32 bit del file binario è installato.
- Se il dispositivo è solo a 64 bit, allora solo la variante a 64 bit del file binario è installato.
Per aggiungere un controllo granulare sulle ABI delle librerie native e dei file binari,
utilizza la
multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries]
proprietà.
first
: corrisponde all'ABI principale del dispositivo. Questa è l'impostazione predefinita file binari.lib32
: corrisponde all'ABI a 32 bit del dispositivo, se supportata.lib64
: corrisponde all'ABI a 64 bit del dispositivo, se supportata.prefer32
: corrisponde all'ABI a 32 bit del dispositivo, se supportata. Se L'ABI a 32 bit non è supportata, corrisponde all'ABI a 64 bit.both
: corrisponde a entrambe le ABI. Questa è l'impostazione predefinitanative_shared_libraries
.
Le proprietà java
, libraries
e prebuilts
sono indipendenti dall'ABI.
Questo esempio riguarda un dispositivo che supporta il formato 32/64 e non preferisce il formato 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
},
},
}
firma vbmeta
Firma ogni APEX con chiavi diverse. Quando è necessaria una nuova chiave, crea un
una coppia di chiavi pubblica/privata e creare un modulo apex_key
. Utilizza la proprietà key
per
firmare l'APEX utilizzando la chiave. La chiave pubblica viene inclusa automaticamente nel
APEX con il nome avb_pubkey
.
# create an rsa key pairopenssl genrsa -out foo.pem 4096
# extract the public key from the key pairavbtool extract_public_key --key foo.pem --output foo.avbpubkey
# in Android.bpapex_key { name: "apex.test.key", public_key: "foo.avbpubkey", private_key: "foo.pem", }
Nell'esempio precedente, 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 runtime,
apexd
verifica l'APEX utilizzando una chiave pubblica con lo stesso ID nel dispositivo.
Firma APEX
Firma gli APEX nello stesso modo in cui firmi gli APK. Firma gli APEX due volte; una volta per
mini file system (apex_payload.img
file) e una volta per l'intero file.
Per firmare un APEX a livello di file, imposta la proprietà certificate
in uno di
questi tre modi:
- Non impostato: se non viene impostato alcun valore, l'APEX è firmato con il certificato situato
alle ore
PRODUCT_DEFAULT_DEV_CERTIFICATE
. Se non viene impostato alcun flag, i valori predefiniti del percorso abuild/target/product/security/testkey
. <name>
: l'APEX è firmato con il certificato<name>
nello stesso comePRODUCT_DEFAULT_DEV_CERTIFICATE
.:<name>
: l'APEX è firmato con il certificato definito dal Modulo presto denominato<name>
. Il modulo del certificato può essere definito come .
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)
}
Installa un APEX
Per installare un APEX, utilizza ADB.
adb install apex_file_name
adb reboot
Se supportsRebootlessUpdate
è impostato su true
in apex_manifest.json
e il valore
l'APEX attualmente installato non è utilizzato (ad esempio, tutti i servizi che contiene hanno
viene interrotto), puoi installare un nuovo APEX senza dover riavviare
Flag --force-non-staged
.
adb install --force-non-staged apex_file_name
Utilizza un APEX
Dopo il riavvio, l'APEX viene montato in /apex/<apex_name>@<version>
. È possibile montare più versioni dello stesso APEX contemporaneamente.
Tra i percorsi di montaggio, quello che corrisponde all'ultima versione è
associazione montata in /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:
- Un OEM o ODM precarica un APEX in
/system/apex
quando il dispositivo spedito. - I file nell'APEX sono accessibili tramite il percorso
/apex/<apex_name>/
. - Quando in
/data/apex
viene installata una versione aggiornata dell'APEX, il percorso punta al nuovo APEX dopo il riavvio.
Aggiornare un servizio con un APEX
Per aggiornare un servizio utilizzando un APEX:
Contrassegna il servizio nella partizione di sistema come aggiornabile. Aggiungi l'opzione
updatable
alla definizione del servizio./system/etc/init/myservice.rc: service myservice /system/bin/myservice class core user system ... updatable
Crea un nuovo file
.rc
per il servizio aggiornato. Utilizza l'opzioneoverride
per ridefinire il servizio esistente./apex/my.apex/etc/init.rc: service myservice /apex/my.apex/bin/myservice class core user system ... override
Le definizioni del servizio possono essere definite solo nel file .rc
di un APEX. Azione
i trigger 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.
Configura il sistema per supportare gli aggiornamenti APEX
Imposta la seguente proprietà di sistema su 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 la vecchia versione
per il supporto completo APEX. Ad esempio, il kernel potrebbe essere stato creato
senza CONFIG_BLK_DEV_LOOP=Y
, fondamentale per il montaggio del file system
all'interno di un APEX.
L'APEX bidimensionale è un APEX appositamente realizzato che può essere attivato sui dispositivi con
un kernel legacy. I file in un APEX bidimensionale vengono installati direttamente in una directory
sotto la partizione integrata. Ad esempio, lib/libFoo.so
in un APEX bidimensionale
my.apex
installato in /system/apex/my.apex/lib/libFoo.so
.
L'attivazione di un APEX bidimensionale non coinvolge il dispositivo loop. L'intero
La directory /system/apex/my.apex
è montata direttamente in associazione a /apex/name@ver
.
Gli APEX bidimensionali non possono essere aggiornati scaricando le versioni aggiornate degli APEX dalla rete perché non è possibile eseguire la suddivisione degli APEX scaricati. Gli APEX bidimensionali possono essere aggiornati soltanto tramite una normale OTA.
La configurazione predefinita è APEX bidimensionale. Ciò significa che tutti Per impostazione predefinita, gli APEX sono bidimensionali, a meno che non configuri esplicitamente il tuo dispositivo per creare APEX non semplificati per supportare gli aggiornamenti APEX (come spiegato sopra).
NON è consentito combinare APEX bidimensionali e non appiattiti in un dispositivo
supportati. Gli APEX di un dispositivo devono essere tutti non appiattiti o tutti appiattiti.
Questo è particolarmente importante quando si spediscono articoli APEX predefiniti
in progetti come Mainline. APEX non prefirmati (creati
il codice sorgente) non deve essere scalato e firmato con chiavi appropriate. La
dispositivo deve ereditare da updatable_apex.mk
come spiegato in
Aggiornare un servizio con un APEX.
APEX compressi
Android 12 e versioni successive offrono la compressione APEX per riducendo l'impatto sullo spazio di archiviazione dei pacchetti APEX aggiornabili. Dopo un aggiornamento di un APEX è installato, sebbene la sua versione preinstallata non sia più utilizzata, occupa ancora la stessa quantità di spazio. Lo spazio occupato rimane non disponibile.
La compressione APEX riduce al minimo l'impatto sullo spazio di archiviazione utilizzando un set altamente compresso
di file APEX su partizioni di sola lettura (come la partizione /system
). Android
12 e versioni successive utilizzano un algoritmo di compressione dei file DEFLATE.
La compressione non offre l'ottimizzazione di quanto segue:
APEX bootstrap che devono essere montati molto presto nel boot sequenza.
APEX non aggiornabili. La compressione è utile solo se è installata una versione aggiornata di un APEX sulla partizione
/data
. Un elenco completo degli APEX aggiornabili è disponibile nella Componenti del sistema modulare .APEX libs condivisi dinamici. Poiché
apexd
attiva sempre entrambe le versioni di quali APEX (preinstallati e con upgrade eseguito), la loro compressione non aggiunge valore.
Formato file APEX compresso
Formato di file APEX compresso.
Figura 2. Formato file APEX compresso
Al livello principale, un file APEX compresso è un file ZIP contenente il file apex in forma sgonfia con un livello di compressione di 9 e con altri file archiviati non compressi.
Un file APEX è formato da quattro file:
original_apex
: sgonfiato con un livello di compressione di 9 Questo è il file APEX originale non compresso.apex_manifest.pb
: solo memorizzatoAndroidManifest.xml
: solo memorizzatoapex_pubkey
: solo memorizzato
I file apex_manifest.pb
, AndroidManifest.xml
e apex_pubkey
sono
dei file corrispondenti in original_apex
.
Creazione di un APEX compresso
La versione APEX compresso può essere creata utilizzando lo strumento apex_compression_tool.py
all'indirizzo
system/apex/tools
Nel sistema di compilazione sono disponibili diversi parametri relativi alla compressione APEX.
In Android.bp
, la compressione di un file APEX è controllata dal
Proprietà compressible
:
apex {
name: "apex.test",
manifest: "apex_manifest.json",
file_contexts: "file_contexts",
compressible: true,
}
Un flag prodotto PRODUCT_COMPRESSED_APEX
consente di stabilire se un'immagine di sistema viene creata
dall'origine deve contenere file APEX compressi.
Per la sperimentazione locale puoi forzare una build a comprimere gli APEX impostando
Da OVERRIDE_PRODUCT_COMPRESSED_APEX=
a true
.
I file APEX compressi generati dal sistema di compilazione hanno l'estensione .capex
.
L'estensione consente di distinguere più facilmente tra contenuti compressi e non compressi
tutte le versioni di un file APEX.
Algoritmi di compressione supportati
Android 12 supporta solo la compressione deflate-zip.
Attiva un file APEX compresso durante l'avvio
Prima che un APEX compresso possa essere attivato, il file original_apex
al suo interno
decompresso nella directory /data/apex/decompressed
. Il risultato
il file APEX decompresso è collegato in modo forzato alla directory /data/apex/active
.
Considera l'esempio che segue per mostrare la procedura descritta in precedenza.
Considera /system/apex/com.android.foo.capex
come un APEX compresso che
con versionCode 37.
- Il file
original_apex
all'interno di/system/apex/com.android.foo.capex
è decompresso in/data/apex/decompressed/com.android.foo@37.apex
. restorecon /data/apex/decompressed/com.android.foo@37.apex
viene eseguita su verifica che abbia un'etichetta SELinux corretta.- I controlli di verifica vengono svolti il giorno
/data/apex/decompressed/com.android.foo@37.apex
per verificarne la validità:apexd
controlla la chiave pubblica nel bundle/data/apex/decompressed/com.android.foo@37.apex
per verificare che sia uguale a quello in bundle in/system/apex/com.android.foo.capex
. - Il file
/data/apex/decompressed/com.android.foo@37.apex
è collegato in modo forzato a nella directory/data/apex/active/com.android.foo@37.apex
. - La normale logica di attivazione per i file APEX non compressi viene eseguita su
/data/apex/active/com.android.foo@37.apex
.
Interazione con OTA
I file APEX compressi hanno implicazioni sulla pubblicazione e sull'applicazione OTA. Dal giorno un aggiornamento OTA potrebbe contenere un file APEX compresso con un livello di versione superiore rispetto a quello attivo su un dispositivo, devi riservare una certa quantità di spazio libero prima del riavvio di un dispositivo per applicare un aggiornamento OTA.
Per supportare il sistema OTA, apexd
espone queste due API binder:
calculateSizeForCompressedApex
: calcola le dimensioni necessarie per la decompressione File APEX in un pacchetto OTA. Può essere usato per verificare che un dispositivo sia spazio a sufficienza prima che un OTA venga scaricato.reserveSpaceForCompressedApex
- riserva spazio sul disco per uso futuro diapexd
per decomprimere i file APEX compressi all'interno del pacchetto OTA.
In caso di aggiornamento OTA A/B, apexd
tenta di decomprimere in
come parte della routine OTA post-installazione. Se la decompressione non riesce,
apexd
esegue la decompressione durante l'avvio e applica l'OTA
aggiornamento.
Alternative prese in considerazione durante lo sviluppo dell'APEX
Ecco alcune opzioni prese in considerazione da AOSP durante la progettazione del file APEX e perché sono stati inclusi o esclusi.
Normali sistemi di gestione dei pacchetti
Le distribuzioni Linux hanno sistemi di gestione dei pacchetti come dpkg
e rpm
,
che sono potenti, mature e solide. Tuttavia, non erano necessarie
adottata per APEX perché non è in grado di proteggere i pacchetti
dell'installazione. La verifica viene eseguita soltanto durante l'installazione dei pacchetti.
Gli utenti malintenzionati possono compromettere l'integrità dei pacchetti installati, passando inosservati. Questo è
una regressione per Android in cui tutti i componenti di sistema erano archiviati in modalità di sola lettura
file system la cui integrità è protetta da dm-verity per ogni I/O. Qualsiasi
le manomissioni dei componenti del sistema devono essere vietate o rilevabili in modo
che il dispositivo può rifiutare l'avvio se compromesso.
Dm-crypt per integrità
I file in un container APEX provengono da partizioni integrate (ad esempio,
/system
) protetti da dm-verity, in cui vengono apportate modifiche
i file sono vietati anche dopo aver montato le partizioni. Per fornire il
lo stesso livello di sicurezza ai file, tutti i file di un APEX sono archiviati in
un'immagine di sistema abbinata a un albero di hash e a un descrittore vbmeta. Senza
dm-verity, un APEX nella partizione /data
è vulnerabile ad attacchi
modifiche apportate dopo la verifica e l'installazione.
Infatti, la partizione /data
è protetta anche da livelli di crittografia come
dm-crypt. Sebbene questo offra un certo livello di protezione dalle manomissioni,
il cui scopo principale è la privacy, non l'integrità. Quando un aggressore ottiene l'accesso ai
/data
, non ci possono essere ulteriori protezioni e anche questa è una
una regressione rispetto a tutti i componenti del sistema che si trovano nella partizione /system
.
L'albero di hash all'interno di un file APEX, insieme a dm-verity, fornisce lo stesso
di protezione dei contenuti.
Percorsi di reindirizzamento da /system a /apex
I file dei componenti di sistema pacchettizzati in un APEX sono accessibili tramite nuovi percorsi come
/apex/<name>/lib/libfoo.so
. Quando i file facevano parte dell'/system
, erano accessibili tramite percorsi come /system/lib/libfoo.so
. R
client di un file APEX (altri file APEX o la piattaforma) deve utilizzare il nuovo
percorsi di addestramento. Potresti dover aggiornare il codice esistente a seguito della modifica del percorso.
Sebbene un modo per evitare la modifica del percorso sia sovrapporre i contenuti del file in una
APEX sulla partizione /system
, il team Android ha deciso di non sovrapporre
nella partizione /system
, perché questo potrebbe influire sulle prestazioni
numero di file sovrapposti (possibilmente anche impilati uno dopo l'altro)
aumentati.
Un'altra opzione era quella di compromettere funzioni di accesso ai file quali open
, stat
e
readlink
, in modo che i percorsi che iniziano con /system
siano stati reindirizzati al proprio
percorsi corrispondenti in /apex
. Il team Android ha ignorato questa opzione
perché non è possibile cambiare tutte le funzioni che accettano percorsi.
Ad esempio, alcune app collegano in modo statico Bionic, che implementa le funzioni.
In questi casi, le app non vengono reindirizzate.