Le sezioni di codice eseguibili per i file binari di sistema AArch64 sono contrassegnate per impostazione predefinita solo esecuzione (non leggibile) come mitigazione di protezione avanzata contro il codice just-in-time e riutilizzare gli attacchi. Codice che combina dati e codice e che lo modifica intenzionalmente esamina queste sezioni (senza prima rimappare i segmenti di memoria come leggibili) non funzionano più. App con SDK target pari a 10 (livello API 29 o superiore) sono interessati se l'app tenta di leggere sezioni di codice di librerie di sistema abilitate per la memoria di sola esecuzione (XOM) in memoria contrassegnando la sezione come leggibile.
Per trarre il massimo vantaggio da questa mitigazione, sia il supporto hardware che kernel sono obbligatorio. Senza questo supporto, la mitigazione potrebbe essere applicata solo parzialmente. La Il kernel comune di Android 4.9 contiene le patch appropriate per fornire per i dispositivi ARMv8.2.
Implementazione
I file binari AArch64 generati dal compilatore presuppongono che il codice e i dati non siano mescolati. L'attivazione di questa funzione non influisce negativamente sulle prestazioni di del dispositivo.
Per il codice che deve eseguire introspezione intenzionale della memoria sul suo
segmenti eseguibili, è consigliabile chiamare mprotect
sul
segmenti di codice che richiedono un'ispezione per consentirne la lettura, quindi
rimuovere la leggibilità al termine dell'ispezione.
Questa implementazione fa sì che le letture nei segmenti di memoria contrassegnati come
solo di esecuzione per generare un errore di segmentazione (SEGFAULT
).
Ciò potrebbe verificarsi a causa di un bug, una vulnerabilità, dati mescolati con
(pooling letterale) o introspezione intenzionale della memoria.
Supporto e impatto dei dispositivi
I dispositivi con hardware precedenti o kernel precedenti (inferiori alla 4.9) senza
le patch richieste potrebbero non supportare completamente questa funzionalità o trarre vantaggio da questa funzionalità. Dispositivi
senza il supporto del kernel non possono imporre gli accessi degli utenti alla memoria di sola esecuzione,
tuttavia il codice kernel che controlla esplicitamente se una pagina è leggibile può
applicare in modo forzato questa proprietà, ad esempio process_vm_readv()
.
Il flag del kernel CONFIG_ARM64_UAO
deve essere impostato nel kernel su
assicurarsi che il kernel rispetti le pagine userland contrassegnate con il valore di sola esecuzione. ARMv8 precedente
i dispositivi o i dispositivi ARMv8.2 con User Access Override (UAO) disabilitato, potrebbero non
sfruttano al massimo questa funzionalità e potrebbero essere ancora in grado di leggere le pagine di sola esecuzione utilizzando
syscall.
Esegui il refactoring del codice esistente
Il codice che è stato trasferito da AArch32 potrebbe contenere dati mescolati e
codice, causando problemi. In molti casi, risolvere questi problemi è semplice
come lo spostamento delle costanti in una sezione .data
del file di assemblaggio.
Potrebbe essere necessario il refactoring dell'assemblaggio scritto a mano per separare l'assemblaggio in un pool locale costanti.
Esempi:
I file binari generati dal compilatore Clang non dovrebbero avere problemi con i dati mescolati nel codice. Se il codice generato dalla GNU compilatore (GCC) viene inclusi (da una libreria statica), esamina il file binario di output per assicurarti che le costanti non siano state raggruppate nelle sezioni di codice.
Se è necessaria l'introspezione del codice nelle sezioni di codice eseguibili,
prima chiama mprotect
per contrassegnare il codice come leggibile. Dopo l'operazione
è completa, chiama di nuovo mprotect
per contrassegnarla come illeggibile.
Abilita XOM
L'opzione Solo esecuzione è abilitata per impostazione predefinita per tutti i file binari a 64 bit nella build di un sistema operativo completo.
Disabilita XOM
È possibile disattivare l'esecuzione solo a livello di modulo, da un'intera struttura di sottodirectory oppure a livello globale per un'intera build.
È possibile disabilitare XOM per singoli moduli che non possono essere sottoposti a refactoring o che devono essere letti
di codice eseguibile impostando il valore LOCAL_XOM
e xom
in false
.
// Android.mk LOCAL_XOM := false // Android.bp cc_binary { // or other module types ... xom: false, }
Se la memoria di sola esecuzione è disabilitata in una libreria statica, il sistema di compilazione applica
a tutti i moduli dipendenti di quella libreria statica. Puoi eseguire l'override
utilizzando xom: true,
.
Per disattivare la memoria di sola esecuzione in una determinata sottodirectory (ad esempio,
foo/bar/), passa il valore a XOM_EXCLUDE_PATHS
.
make -j XOM_EXCLUDE_PATHS=foo/bar
In alternativa, puoi impostare PRODUCT_XOM_EXCLUDE_PATHS
nella configurazione del prodotto.
Puoi disabilitare globalmente i file binari di sola esecuzione passandoli
ENABLE_XOM=false
al comando make
.
make -j ENABLE_XOM=false
Convalida
Non sono disponibili test CTS o di verifica solo per l'esecuzione
la memoria. Puoi verificare manualmente i file binari utilizzando readelf
e controllando
i flag del segmento.