Per informazioni su come leggere i report di arresto anomalo di HWASan, consulta la pagina Informazioni sui report di HWASan.
Hardware-assisted AddressSanitizer (HWASan) è uno strumento di rilevamento degli errori di memoria simile a AddressSanitizer. HWASan utilizza molta meno RAM rispetto ad ASan, il che lo rende adatto alla sanificazione dell'intero sistema. HWASan è disponibile solo su Android 10 e versioni successive e solo su hardware AArch64.
Sebbene sia utile principalmente per il codice C/C++, HWASan può anche aiutare a eseguire il debug del codice Java che causa arresti anomali in C/C++ utilizzato per implementare le interfacce Java. È utile perché rileva gli errori di memoria quando si verificano, indirizzandoti direttamente al codice responsabile.
Rispetto al classico ASan, HWASan ha:
- Un sovraccarico della CPU simile (~2x)
- Un sovraccarico delle dimensioni del codice simile (40-50%)
- Un sovraccarico della RAM molto inferiore (10-35%)
HWASan rileva lo stesso insieme di bug di ASan:
- Overflow/underflow del buffer dello stack e dell'heap
- Utilizzo dell'heap dopo la liberazione
- Utilizzo dello stack al di fuori dell'ambito
- Liberazione doppia/liberazione non valida
Inoltre, HWASan rileva l'utilizzo dello stack dopo il ritorno.
HWASan (come ASan) è compatibile con UBSan, entrambi possono essere abilitati su una destinazione contemporaneamente.
Dettagli e limitazioni dell'implementazione
HWASan si basa sull' approccio di tagging della memoria, in cui un piccolo valore di tag casuale viene associato sia ai puntatori sia agli intervalli di indirizzi di memoria. Affinché un accesso alla memoria sia valido, i tag del puntatore e della memoria devono corrispondere. HWASan si basa sulla funzionalità di ignorare il byte superiore (TBI) di ARMv8, chiamata anche tagging degli indirizzi virtuali, per memorizzare il tag del puntatore nei bit più alti dell'indirizzo.
Puoi scoprire di più sulla progettazione di HWASan nel sito della documentazione di Clang.
Per progettazione, HWASan non ha le redzone di dimensioni limitate di ASan per il rilevamento degli overflow o la quarantena di capacità limitata di ASan per il rilevamento dell'utilizzo dopo la liberazione. Per questo motivo, HWASan può rilevare un bug indipendentemente dalle dimensioni dell'overflow o dal tempo trascorso dalla deallocazione della memoria. Questo conferisce a HWASan un grande vantaggio rispetto ad ASan.
Tuttavia, HWASan ha un numero limitato di valori di tag possibili (256), il che significa che esiste una probabilità dello 0,4% di non rilevare un bug durante un'esecuzione del programma.
Requisiti
Le versioni recenti (4.14 e successive) del kernel Android comune supportano HWASan immediatamente. I rami specifici di Android 10 non supportano HWASan.
Il supporto di userspace per HWASan è disponibile a partire da Android 11.
Se utilizzi un kernel diverso, HWASan richiede che il kernel Linux accetti i puntatori con tag negli argomenti delle chiamate di sistema. Il supporto per questa funzionalità è stato implementato nei seguenti patchset upstream:
- ABI degli indirizzi con tag arm64
- arm64: rimuovi i tag dai puntatori utente passati al kernel
- mm: evita di creare alias di indirizzi virtuali in brk()/mmap()/mremap()
- arm64: convalida gli indirizzi con tag in access_ok() chiamati dai thread del kernel
Se esegui la build con una toolchain personalizzata, assicurati che includa tutto fino al commit c336557f di LLVM.
Utilizzare HWASan
Utilizza i seguenti comandi per creare l'intera piattaforma utilizzando HWASan:
lunch aosp_walleye-userdebug # (or any other product)export SANITIZE_TARGET=hwaddressm -j
Per comodità, puoi aggiungere l'impostazione SANITIZE_TARGET a una definizione di prodotto, in modo simile a aosp_coral_hwasan.
Per gli utenti che conoscono AddressSanitizer, gran parte della complessità della build è scomparsa:
- Non è necessario eseguire make due volte.
- Le build incrementali funzionano immediatamente.
- Non è necessario eseguire il flash di userdata.
Sono state rimosse anche alcune limitazioni di AddressSanitizer:
- Gli eseguibili statici sono supportati.
- È possibile saltare la sanificazione di qualsiasi target diverso da libc. A differenza di ASan, non è necessario che, se una libreria viene sanificata, lo sia anche qualsiasi eseguibile che la collega.
È possibile passare liberamente da HWASan alle immagini normali con lo stesso numero di build (o superiore). Non è necessario cancellare i dati del dispositivo.
Per saltare la sanificazione di un modulo, utilizza
LOCAL_NOSANITIZE := hwaddress (Android.mk) o
sanitize: { hwaddress: false } (Android.bp).
Sanificare i target individuali
HWASan può essere abilitato per target in una build normale (non sanificata), a condizione che anche libc.so sia anche
sanificata. Aggiungi hwaddress: true al blocco sanitize in "libc_defaults"
in bionic/libc/Android.bp. Poi fai lo stesso nel target su cui stai lavorando.
Tieni presente che la sanificazione di libc consente di taggare le allocazioni di memoria heap a livello di sistema, nonché di
controllare i tag per le operazioni di memoria all'interno di libc.so. In questo modo è possibile rilevare i bug anche nei file binari
in cui HWASan non è stato abilitato se l'accesso alla memoria errato si trova in libc.so
(ad es. pthread_mutex_unlock() su un mutex delete()ed).
Non è necessario modificare alcun file di build se l'intera piattaforma viene creata utilizzando HWASan.
Analisi dello stack migliori
HWASan utilizza un unwinder rapido basato su puntatori di frame per registrare un'analisi dello stack
per ogni evento di allocazione e deallocazione della memoria nel
programma. Android abilita i puntatori di frame nel codice AArch64 per impostazione predefinita,
quindi in pratica funziona perfettamente. Se devi eseguire l'unwind tramite
codice gestito, imposta HWASAN_OPTIONS=fast_unwind_on_malloc=0
nell'ambiente del processo. Tieni presente che le analisi dello stack di accesso alla memoria errato
utilizzano l'unwinder "lento" per impostazione predefinita. Questa impostazione influisce solo sulle
analisi di allocazione e deallocazione. Questa opzione può richiedere un utilizzo intensivo della CPU, a seconda del carico.
Simbolizzazione
Consulta la sezione Simbolizzazione in "Informazioni sui report di HWASan".
HWASan nelle app
Analogamente ad AddressSanitizer, HWASan non può vedere il codice Java, ma può rilevare i bug nelle librerie JNI. Fino ad Android 14, l'esecuzione di app HWASan su un dispositivo non HWASan era non supportata.
Su un dispositivo HWASan, le app possono essere controllate con HWASan creando il loro
codice con SANITIZE_TARGET:=hwaddress in
Make o -fsanitize=hwaddress nei flag del compilatore.
Su un dispositivo non HWASan (con Android 14 o versioni successive), è necessario aggiungere un file wrap.sh che imposta
LD_HWASAN=1
Per maggiori dettagli, consulta la
documentazione per gli sviluppatori di app.