Runtime addressSanitizer
La libreria di runtime AddressSanitizer intercetta le funzioni e le operazioni comuni di allocazione della memoria per consentire l'ispezione degli accessi alla memoria. Esistono diverse librerie di runtime che supportano i vari tipi di eseguibili che il compilatore può generare. Il compilatore e il linker collegano automaticamente le librerie di runtime appropriate, purché passi l'opzione /fsanitize=address
in fase di compilazione. È possibile eseguire l'override del comportamento predefinito usando l'opzione /NODEFAULTLIB
in fase di collegamento. Per altre informazioni, vedere la sezione sul collegamento nel linguaggio AddressSanitizer, nella compilazione e nel debug di riferimento.
Durante la compilazione con cl /fsanitize=address
, il compilatore genera istruzioni per gestire e controllare i byte shadow. Il programma usa questa strumentazione per controllare gli accessi alla memoria nello stack, nell'heap o nell'ambito globale. Il compilatore produce anche metadati che descrivono lo stack e le variabili globali. Questi metadati consentono al runtime di generare una diagnostica degli errori precisa: nomi di funzione, righe e colonne nel codice sorgente. In combinazione, i controlli del compilatore e le librerie di runtime possono diagnosticare con precisione molti tipi di bug di sicurezza della memoria se vengono rilevati in fase di esecuzione.
Di seguito è riportato l'elenco delle librerie di runtime per il collegamento al runtime AddressSanitizer, a partire da Visual Studio 17.7 Preview 3. Per altre informazioni sulle /MT
opzioni (collegare in modo statico il runtime) e /MD
(collegare dinamicamente le opzioni redist in fase di esecuzione), vedere /MD, /MT, /LD (Use Run-Time Library).
Nota
Nella tabella seguente è {arch}
i386
o x86_64
.
Queste librerie usano convenzioni Clang per i nomi di architettura. Le convenzioni MSVC sono in genere x86
e anziché i386
e x86_64
x64
, ma fanno riferimento alle stesse architetture.
Opzione CRT | Libreria di runtime AddressSanitizer (.lib) | File binario di runtime degli indirizzi (.dll) |
---|---|---|
/MT oppure /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD oppure /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
Il diagramma seguente mostra come le librerie di runtime del linguaggio sono collegate per le opzioni del /MT
compilatore , /MTd
, /MD
e /MDd
:
L'immagine mostra tre scenari per il collegamento della libreria di runtime. Il primo è /MT o /MTd. My_exe.exe e my_dll.dll vengono entrambi visualizzati con le proprie copie dei runtime VCRuntime, Universal CRT e C++ collegati staticamente. Gli scenari mostrano /MD in cui my_exe.exe e my_dll.dll condividono vcruntime140.dll, ucrtbase.dll e msvcp140.dll. L'ultimo scenario mostra /MDd in cui sia my_exe.exe che my_dll.dll condividono le versioni di debug dei runtime: vcruntime140d.dll, ucrtbased.dll e msvcp140d.dll
Il diagramma seguente mostra come la libreria ASan è collegata per varie opzioni del compilatore:
L'immagine mostra quattro scenari per il collegamento della libreria di runtime ASan. Gli scenari sono per /MT (collegare in modo statico il runtime), /MTd (collegare in modo statico il runtime di debug), /MD (collegare dinamicamente il redist in fase di esecuzione), /MDd (collegare dinamicamente il debug redist in fase di esecuzione). In tutti i casi, my_exe.exe collegamenti e i relativi associati my_dll.dll collegamento a una singola istanza di clang-rt.asan-dynamix-x86_64.dll.
Anche quando si esegue il collegamento statico, la DLL di runtime ASan deve essere presente in fase di esecuzione, a differenza di altri componenti di runtime C.
Versioni precedenti
Prima di Visual Studio 17.7 Preview 3, le compilazioni collegate staticamente (/MT
o /MTd
) non usava una dipendenza DLL. Al contrario, il runtime AddressSanitizer è stato collegato staticamente al file EXE dell'utente. I progetti DLL caricano quindi le esportazioni dal file EXE dell'utente per accedere alla funzionalità ASan.
I progetti collegati dinamicamente (/MD
o /MDd
) usavano librerie e DLL diverse a seconda che il progetto sia stato configurato per il debug o la versione. Per altre informazioni su queste modifiche e sulle relative motivazioni, vedere MSVC Address Sanitizer – One DLL for all Runtime Configurations (Sanificatori indirizzi MSVC - Una DLL per tutte le configurazioni di runtime).
La tabella seguente descrive il comportamento precedente del collegamento della libreria di runtime AddressSanitizer prima di Visual Studio 17.7 Preview 3:
Opzione CRT | DLL o EXE | DEBUG? | Libreria ASan (.lib ) |
File binario di runtime ASan (.dll ) |
---|---|---|---|---|
/MT |
EXE | No | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
None |
/MT |
DLL | No | clang_rt.asan_dll_thunk-{arch} |
None |
/MD |
O | No | clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MT |
EXE | Sì | clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
None |
/MT |
DLL | Sì | clang_rt.asan_dbg_dll_thunk-{arch} |
None |
/MD |
Prima o dopo | Sì | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dbg_dynamic-{arch} |
Il diagramma seguente mostra come la libreria ASan è stata collegata per varie opzioni del compilatore prima di Visual Studio 2022 17.7 Preview 3:
L'immagine mostra quattro scenari per il collegamento della libreria di runtime ASan. Gli scenari sono per /MT (collegare in modo statico il runtime), /MTd (collegare in modo statico il runtime di debug), /MD (collegare dinamicamente il redist in fase di esecuzione), /MDd (collegare dinamicamente il debug redist in fase di esecuzione). Per /MT, my_exe.exe ha una copia collegata staticamente del runtime ASan. my_dll.dll collegamenti al runtime ASan in my_exe.exe. Per /MTd, il diagramma è lo stesso, ad eccezione del fatto che usa il runtime ASan collegato staticamente al debug. Per /MD, sia my_exe.exe che my_dll.dll collegamento al runtime ASan collegato dinamicamente denominato clang_rt.asan_dynamic-x86_64.dll. Per /MDd, il diagramma è identico ad eccezione di my_exe.exe e my_dll.dll collegamento al runtime ASan di debug denominato clang_rt.asan_dbg_dynamic-x86_64.dll.
Intercettazione di funzioni
AddressSanitizer ottiene l'intercettazione delle funzioni tramite molte tecniche di hotpatching. Queste tecniche sono meglio documentate all'interno del codice sorgente stesso.
Le librerie di runtime intercettano molte funzioni comuni di gestione della memoria e manipolazione della memoria. Per un elenco, vedere l'elenco AddressSanitizer delle funzioni intercettate. Gli intercettori di allocazione gestiscono i metadati e i byte shadow correlati a ogni chiamata di allocazione. Ogni volta che viene chiamata una funzione CRT, malloc
ad esempio o delete
, gli intercettori impostano valori specifici nell'area shadow-memory AddressSanitizer per indicare se tali posizioni dell'heap sono attualmente accessibili e quali sono i limiti dell'allocazione. Questi byte shadow consentono ai controlli generati dal compilatore dei byte shadow di determinare se un carico o un archivio è valido.
L'intercettazione non garantisce l'esito positivo. Se un prologo di funzione è troppo breve per la scrittura di un oggetto jmp
, l'intercettazione può non riuscire. Se si verifica un errore di intercettazione, il programma genera un'eccezione debugbreak
e si interrompe. Se si collega un debugger, la causa del problema di intercettazione è chiara. In caso di problema, segnalare un bug.
Nota
Facoltativamente, gli utenti possono tentare di continuare oltre un'intercettazione non riuscita impostando la variabile ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE
di ambiente su qualsiasi valore. Se si continua a superare un errore di intercettazione, è possibile che i report di bug per tale funzione non siano stati rilevati.
Allocatori personalizzati e runtime AddressSanitizer
Il runtime AddressSanitizer fornisce intercettori per interfacce di allocatore comuni, malloc
/free
, new
/delete
,/HeapFree
HeapAlloc
(tramite ).RtlAllocateHeap
/RtlFreeHeap
Molti programmi usano allocatori personalizzati per un motivo o un altro, un esempio è qualsiasi programma che usa dlmalloc
o una soluzione usando l'interfaccia std::allocator
e VirtualAlloc()
. Il compilatore non è in grado di aggiungere automaticamente chiamate di gestione della memoria shadow a un allocatore personalizzato. È responsabilità dell'utente usare l'interfaccia di avvelenamento manuale fornita. Questa API consente a questi allocatori di funzionare correttamente con il runtime AddressSanitizer esistente e le convenzioni dei byte shadow.
Interfaccia di avvelenamento manuale AddressSanitizer
L'interfaccia per il riconoscimento dei dati è semplice, ma impone restrizioni di allineamento all'utente. Gli utenti possono importare questi prototipi importando sanitizer/asan_interface.h
. Ecco i prototipi di funzione di interfaccia:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Per praticità, il file di intestazione dell'interfaccia AddressSanitizer fornisce macro wrapper. Queste macro controllano se la funzionalità AddressSanitizer è abilitata durante la compilazione. Consentono al codice sorgente di omettere le chiamate di funzione di avvelenamento quando non sono necessarie. Queste macro devono essere preferite rispetto alla chiamata diretta delle funzioni precedenti:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Requisiti di allineamento per l'avvelenamento addressSanitizer
Qualsiasi avvelenamento manuale dei byte di ombreggiatura deve considerare i requisiti di allineamento. Se necessario, l'utente deve aggiungere spaziatura interna, in modo che i byte shadow finisno su un limite di byte nella memoria shadow. Ogni bit nella memoria shadow AddressSanitizer codifica lo stato di un singolo byte nella memoria dell'applicazione. Questa codifica indica la dimensione totale di ogni allocazione, inclusa qualsiasi spaziatura interna, deve essere allineata a un limite di 8 byte. Se il requisito di allineamento non è soddisfatto, può causare segnalazioni di bug non corrette. La segnalazione errata potrebbe manifestarsi come report mancanti (falsi negativi) o report su errori (falsi positivi).
Per un'illustrazione dei requisiti di allineamento e dei potenziali problemi, vedere gli esempi di allineamento di ASan forniti. Uno è un piccolo programma per mostrare cosa può andare storto con l'avvelenamento manuale della memoria shadow. Il secondo è un esempio di implementazione dell'avvelenamento manuale usando l'interfaccia std::allocator
.
Opzioni di runtime
Microsoft C/C++ (MSVC) usa un runtime basato sul runtime Clang AddressSanitizer dal repository llvm-project. Per questo motivo, la maggior parte delle opzioni di runtime viene condivisa tra le due versioni. Un elenco completo delle opzioni di runtime Clang pubbliche è disponibile qui. Vengono illustrate alcune differenze nelle sezioni che seguono. Se si individuano opzioni che non funzionano come previsto, segnalare un bug.
Opzioni AddressSanitizer non supportate
- detect_container_overflow
- unmap_shadow_on_exit
Nota
L'opzione halt_on_error
di runtime AddressSanitizer non funziona nel modo previsto. Sia in Clang che nelle librerie di runtime MSVC, molti tipi di errore sono considerati non continuabili, tra cui la maggior parte degli errori di danneggiamento della memoria.
Per altre informazioni, vedere la sezione Differenze con Clang 12.0 .
Opzioni di runtime addresssanitizer specifiche di MSVC
windows_hook_legacy_allocators
Valore booleano, impostato sufalse
per disabilitare l'intercettazione diGlobalAlloc
eLocalAlloc
gli allocatori.Nota
L'opzione
windows_hook_legacy_allocators
non era disponibile nel runtime llvm-project pubblico al momento della scrittura di questo articolo. Alla fine l'opzione può essere conserci al progetto pubblico; Tuttavia, dipende dalla revisione del codice e dall'accettazione della community.L'opzione
windows_hook_rtl_allocators
, in precedenza una funzionalità di consenso esplicito mentre AddressSanitizer era sperimentale, è ora abilitata per impostazione predefinita. Nelle versioni precedenti a Visual Studio 2022 versione 17.4.6, il valore predefinito dell'opzione èfalse
. In Visual Studio 2022 versione 17.4.6 e versioni successive, l'opzionewindows_hook_rtl_allocators
predefinita ètrue
.iat_overwrite
Stringa, impostata su per"error"
impostazione predefinita. Altri valori possibili sono"protect"
e"ignore"
. Alcuni moduli possono sovrascrivere gliimport address table
altri moduli per personalizzare le implementazioni di determinate funzioni. Ad esempio, i driver in genere forniscono implementazioni personalizzate per hardware specifico. L'opzioneiat_overwrite
gestisce la protezione del runtime AddressSanitizer da sovrascrizioni per funzioni specifichememoryapi.h
. Il runtime tiene attualmente traccia delleVirtualAlloc
funzioni ,VirtualProtect
eVirtualQuery
per la protezione. Questa opzione è disponibile in Visual Studio 2022 versione 17.5 Preview 1 e versioni successive. I valori seguentiiat_overwrite
controllano la modalità di reazione del runtime quando le funzioni protette vengono sovrascritte:- Se impostato su
"error"
(impostazione predefinita), il runtime segnala un errore ogni volta che viene rilevata una sovrascrittura. - Se impostato su
"protect"
, il runtime tenta di evitare di usare la definizione sovrascritta e procede. In effetti, la definizione originalememoryapi
della funzione viene usata dall'interno del runtime per evitare ricorsioni infinite. Altri moduli del processo usano ancora la definizione sovrascritta. - Se impostato su
"ignore"
, il runtime non tenta di correggere le funzioni sovrascritte e procede con l'esecuzione.
- Se impostato su
windows_fast_fail_on_error
Boolean (false per impostazione predefinita), impostato sutrue
per consentire al processo di terminare con un __fastfail(71) dopo la stampa del report degli errori.
Nota
Quando abort_on_error valore è impostato su true, in Windows il programma termina con un exit(3). Per non modificare il comportamento corrente, abbiamo deciso di introdurre questa nuova opzione. Se sia abort_on_error che windows_fast_fail_on_error sono true, il programma verrà chiuso con il __fastfail.
Elenco AddressSanitizer di funzioni intercettate (Windows)
Il runtime AddressSanitizer esegue l'hotpating di molte funzioni per abilitare i controlli di sicurezza della memoria in fase di esecuzione. Ecco un elenco non esaustivo delle funzioni monitorate dal runtime AddressSanitizer.
Intercettori predefiniti
__C_specific_handler
(solo x64)_aligned_free
_aligned_malloc
_aligned_msize
_aligned_realloc
_calloc_base
_calloc_crt
_calloc_dbg
(solo runtime di debug)_except_handler3
(solo x86)_except_handler4
(solo x86) (non documentato)_expand
_expand_base
(non documentato)_expand_dbg
(solo runtime di debug)_free_base
(non documentato)_free_dbg
(solo runtime di debug)_malloc_base
(non documentato)_malloc_crt
(non documentato)_malloc_dbg
(solo runtime di debug)_msize
_msize_base
(non documentato)_msize_dbg
(solo runtime di debug)_realloc_base
(non documentato)_realloc_crt
(non documentato)_realloc_dbg
(solo runtime di debug)_recalloc
_recalloc_base
(non documentato)_recalloc_crt
(non documentato)_recalloc_dbg
(solo runtime di debug)_strdup
atoi
atol
calloc
CreateThread
free
frexp
longjmp
malloc
memchr
memcmp
memcpy
memmove
memset
RaiseException
realloc
RtlAllocateHeap
RtlCreateHeap
RtlDestroyHeap
RtlFreeHeap
RtlRaiseException
RtlReAllocateHeap
(non documentato)RtlSizeHeap
(non documentato)SetUnhandledExceptionFilter
strcat
strchr
strcmp
strcpy
strcspn
strdup
strlen
strncat
strncmp
strncpy
strnlen
strpbrk
strspn
strstr
strtok
strtol
wcslen
wcsnlen
Intercettori facoltativi
Gli intercettori elencati di seguito vengono installati solo quando è abilitata un'opzione di runtime AddressSanitizer. Impostare windows_hook_legacy_allocators
su per false
disabilitare l'intercettazione dell'allocatore legacy.
set ASAN_OPTIONS=windows_hook_legacy_allocators=false
GlobalAlloc
GlobalFree
GlobalHandle
GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
LocalAlloc
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock
Vedi anche
Panoramica di AddressSanitizer
Problemi noti di AddressSanitizer
Riferimento alla compilazione e al linguaggio AddressSanitizer
Byte ombreggiatura AddressSanitizer
AddressSanitizer cloud o test distribuiti
Integrazione del debugger AddressSanitizer
Esempi di errore addressSanitizer