A partire da Android 11, per i processi a 64 bit, tutte le allocazioni dell'heap hanno un tag definito dall'implementazione impostato nel byte superiore del puntatore sui dispositivi con supporto del kernel per ARM Top-byte Ignore (TBI). Qualsiasi applicazione che modifichi questo tag viene terminata quando il tag viene verificato durante la deallocazione. Ciò è necessario per l'hardware futuro con supporto ARM Memory Tagging Extension (MTE).
Ignora byte superiore
La funzione Ignora byte superiore di ARM è disponibile per il codice a 64 bit in tutto l'hardware Armv8 AArch64. Questa funzione significa che l'hardware ignora il byte superiore di un puntatore quando accede alla memoria.
TBI richiede unkernel compatibile che gestisca correttamente i puntatori con tag passati dallo spazio utente. I kernel comuni Android da 4.14 (Pixel 4) e versioni successive presentano le patch TBI richieste.
I dispositivi con il supporto TBI nel kernel vengono rilevati dinamicamente all'inizio del processo e un tag dipendente dall'implementazione viene inserito nel byte superiore del puntatore per tutte le allocazioni dell'heap. Successivamente, viene eseguito un controllo per assicurarsi che il tag non sia stato troncato durante la deallocazione della memoria.
Pronto per l'estensione di tagging della memoria
La Memory Tagging Extension (MTE) di ARM aiuta a risolvere i problemi di sicurezza della memoria. MTE funziona contrassegnando i bit di indirizzo dal 56° al 59° di ciascuna allocazione di memoria nello stack, nell'heap e nei globali. L'hardware e il set di istruzioni controllano automaticamente che il tag corretto sia utilizzato ad ogni accesso alla memoria.
Le app Android che memorizzano in modo errato le informazioni nel byte superiore del puntatore hanno la garanzia di interrompersi su un dispositivo abilitato per MTE . I puntatori contrassegnati semplificano il rilevamento e il rifiuto di utilizzi errati del byte superiore del puntatore prima che i dispositivi MTE siano disponibili.
Supporto per gli sviluppatori
Se la tua app si è arrestata in modo anomalo e ti è stato richiesto questo collegamento, potrebbe significare uno dei seguenti:
- L'applicazione ha tentato di liberare un puntatore che non è stato allocato dall'allocatore di heap del sistema.
- Qualcosa nella tua app ha modificato il byte superiore di un puntatore. Il byte superiore del puntatore non può essere modificato e il codice deve essere modificato per risolvere questo problema.
Esempi di puntatore al byte superiore utilizzato o modificato in modo non corretto.
- I puntatori a un tipo particolare hanno metadati specifici dell'applicazione archiviati nei primi 16 bit di indirizzo.
- Un puntatore cast per raddoppiare e poi tornare indietro, perdendo i bit di indirizzo inferiori.
- Il codice calcola la differenza tra gli indirizzi di variabili locali da diversi stack frame come modo per misurare la profondità di ricorsione.
Alcune applicazioni possono dipendere da librerie che si comportano in modo non corretto quando è impostato il byte superiore del puntatore. Riconosciamo che potrebbe non essere banale risolvere rapidamente questi problemi di fondo nelle biblioteche. Di conseguenza, le applicazioni che usano targetSdkLevel < 30
non avranno la codifica del puntatore abilitata per impostazione predefinita. Forniamo anche una via di fuga per le applicazioni create con targetSdkLevel >= 30
per facilitare il periodo di transizione.
Il tratteggio di escape viene utilizzato aggiungendo quanto segue al file AndroidManifest.xml
:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
Ciò disabiliterà la funzione di codifica del puntatore per la tua applicazione. Si noti che ciò non risolve il problema di integrità del codice sottostante. Questo portello di fuga scomparirà nelle versioni future di Android, perché problemi di questo tipo saranno incompatibili con MTE .