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 l'ignoramento del byte superiore ARM (TBI). Qualsiasi app che modifichi questo tag viene terminata quando il tag viene controllato durante la deallocazione. Questo è necessario per l'hardware futuro con il supporto di MTE (Memory Tagging Extension) ARM.
Ignora byte superiore
La funzionalità di ignoramento del byte superiore di ARM è disponibile per il codice a 64 bit in tutto l'hardware Armv8 AArch64. Questa funzionalità indica che l'hardware ignora il byte superiore di un puntatore quando accede alla memoria.
TBI richiede un kernel compatibile che gestisca correttamente i puntatori con tag passati dallo spazio utente. I kernel Android comuni dalla versione 4.14 (Pixel 4) e successive includono le patch TBI richieste.
I dispositivi con il supporto TBI nel kernel vengono rilevati dinamicamente al momento dell'avvio del processo e un tag dipendente dall'implementazione viene inserito nel primo byte del puntatore per tutte le allocazioni dell'heap. Dopodiché viene eseguito un controllo per verificare che il tag non sia stato troncato durante la deallocazione della memoria.
Idoneità all'estensione Memory Tagging
La funzionalità MTE (Memory Tagging Extension) di ARM aiuta a risolvere i problemi di sicurezza della memoria. MTE funziona tagging i bit di indirizzo 56-59 di ogni allocazione di memoria sullo stack, nell'heap e nei dati globali. L'hardware e l'istruzione controllano automaticamente che venga utilizzato il tag corretto a ogni accesso alla memoria.
Le app per Android che memorizzano in modo errato le informazioni nel byte superiore del cursore non funzioneranno su un dispositivo con MTE abilitato. I puntatori con tag semplificano il rilevamento e il rifiuto di utilizzi errati del primo byte del puntatore prima che siano disponibili i dispositivi MTE.
Assistenza per gli sviluppatori
Se la tua app ha avuto un arresto anomalo e ti è stato mostrato questo link, potrebbe significare uno dei seguenti motivi:
- L'app ha cercato di liberare un puntatore che non è stato allocato dall'allocatore dell'heap del sistema.
- Qualcosa nella tua app ha modificato il byte superiore di un puntatore. Il byte superiore del cursore non può essere modificato e il codice deve essere modificato per risolvere il problema.
Esempi di utilizzo o modifica errati dell'indicatore del byte superiore.
- I puntatori a un determinato tipo hanno metadati specifici dell'app memorizzati nei 16 bit di indirizzo iniziali.
- Un puntatore sottoposto a conversione in doppio e poi di nuovo in singolo, perdendo i bit di indirizzo più bassi.
- Codice che calcola la differenza tra gli indirizzi delle variabili locali di diversi frame di stack come metodo per misurare la profondità della ricorsione.
Alcune app potrebbero dipendere da librerie che si comportano in modo errato quando è impostato il byte superiore del puntatore. Siamo consapevoli che potrebbe essere difficile risolvere rapidamente questi problemi di fondo nelle librerie. Di conseguenza,
nelle app che utilizzano targetSdkLevel < 30
non sarà abilitato il tagging dei cursori per impostazione predefinita. Forniamo inoltre un'opzione di ripiego per le app create con targetSdkLevel >= 30
per semplificare il periodo di transizione.
Per utilizzare la sequenza di estrazione, aggiungi quanto segue al tuo
file AndroidManifest.xml
:
<application android:allowNativeHeapPointerTagging="false"> ... </application>
In questo modo viene disattivata la funzionalità di tagging dei cursori per la tua app. Tuttavia, non viene risolto il problema di salute del codice sottostante. Questa via di fuga scomparirà nelle future versioni di Android, perché i problemi di questo tipo non saranno compatibili con MTE.