Modul runtime AddressSanitizer
Knihovna modulu runtime AddressSanitizer zachycuje běžné funkce a operace přidělování paměti, které umožňují kontrolu přístupu k paměti. Existuje několik různých knihoven modulu runtime, které podporují různé typy spustitelných souborů, které může kompilátor generovat. Kompilátor a linker automaticky propojí příslušné knihovny modulu runtime, pokud parametr předáte /fsanitize=address v době kompilace. Výchozí chování můžete přepsat pomocí možnosti /NODEFAULTLIB v době propojení. Další informace najdete v části týkající se propojení v referenčních informacích k jazyku AddressSanitizer, sestavení a ladění.
Níže je uvedený inventář knihoven modulu runtime pro propojení s runtime AddressSanitizer, kde {arch} je nebo i386x86_64 .
Poznámka
Tyto knihovny udržují konvence Clang pro názvy architektur. Konvence MSVC jsou obvykle x86 a x64, a ne i386 a x86_64. Odkazují na stejné architektury.
| Možnost CRT | DLL nebo EXE | LADĚNÍ? | Knihovny binárních souborů modulu runtime AddressSanitizer |
|---|---|---|---|
| MT | EXE | NO | clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch} |
| MT | DLL | NO | clang_rt.asan_dll_thunk-{arch} |
| MD | BUĎ | NO | clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch} |
| MT | EXE | ANO | clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch} |
| MT | DLL | ANO | clang_rt.asan_dbg_dll_thunk-{arch} |
| MD | BUĎ | ANO | clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
Při kompilaci s cl /fsanitize=address vygeneruje kompilátor instrukce pro správu a kontrolu cl /fsanitize=address. Program používá tuto instrumentaci ke kontrole přístupu k paměti v zásobníku, v haldě nebo v globálním oboru. Kompilátor také vytváří metadata popisující zásobník a globální proměnné. Tato metadata umožňují modulu runtime generovat přesnou diagnostiku chyb: názvy funkcí, řádky a sloupce ve zdrojovém kódu. V kombinaci s kontrolami kompilátoru a knihovnami modulu runtime dokáže přesně diagnostikovat mnoho typů chyb zabezpečení paměti, pokud k tomu dochází za běhu.
Zachycení funkce
AddressSanitizer dosahuje zachycení funkcí mnoha technikami oprav zatížení. Tyto techniky jsou nejlépe zdokumentované ve zdrojovém kódu samotném.
Knihovny modulu runtime zachycuje mnoho běžných funkcí správy paměti a manipulace s pamětí. Seznam najdete v tématu Seznam zachycovaných funkcí AddressSanitizer. Zachytávače přidělení spravují metadata a stínové bajty související s každým voláním přidělení. Pokaždé, když je volána funkce CRT, jako je nebo , zachycovače nastaví konkrétní hodnoty v oblasti stínové paměti malloc AddressSanitizer, aby indikují, jestli jsou tato umístění haldy aktuálně dostupná a jaké jsou meze delete přidělení. Tyto stínové bajty umožňují kontrolám stínových bajtů generovaným kompilátorem určit, zda je zatížení nebo úložiště platné.
Zachycování není zaručeno, že bude úspěšné. Pokud je prologa funkce příliš krátká na jmp to, aby byla zapsána, zachycení může selhat. Pokud dojde k selhání zachycení, program vyvolá a debugbreak zastaví. Pokud připojíte ladicí program, je příčina problému se zachycením jasná. Pokud máte tento problém, nahlásit chybu.
Poznámka
Uživatelé se mohou volitelně pokusit pokračovat po neúspěšném zachycení nastavením proměnné prostředí ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE na libovolnou hodnotu. Nepřetržitá chyba zachycení může vést k vynechání zpráv o chybách pro tuto funkci.
Vlastní alokátory a modul runtime AddressSanitizer
Modul runtime AddressSanitizer poskytuje zachytávací moduly pro běžná rozhraní alokátoru malloc/free , new/deleteHeapAlloc/HeapFree , (prostřednictvím RtlAllocateHeap/RtlFreeHeap ). Mnoho programů používá vlastní alokátory z jednoho nebo druhého důvodu. Příkladem může být jakýkoli program používající nebo řešení dlmalloc využívající rozhraní a std::allocatorVirtualAlloc() . Kompilátor nemůže automaticky přidat volání správy stínové paměti do vlastního alokátoru. Uživatel zodpovídá za použití poskytnutého rozhraní pro ruční poisoning. Toto rozhraní API umožňuje těmto alokátorům správně fungovat s existujícími konvencemi modulu runtime AddressSanitizer a stínového byte.
Ruční rozhraní pro zpracování poisoningu AddressSanitizer
Rozhraní pro natážení je jednoduché, ale na uživatele má omezení zarovnání. Uživatelé mohou tyto prototypy importovat importem sanitizer/asan_interface.h . Tady jsou prototypy funkcí rozhraní:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Pro usnadnění poskytuje hlavičkový soubor rozhraní AddressSanitizer obálková makra. Tato makra zkontrolují, jestli je během kompilace povolená funkce AddressSanitizer. Umožňují vašemu zdrojovému kódu vynechat volání nezávolné funkce, když nejsou potřeba. Tato makra by měla být upřednostňována před voláním výše uvedených funkcí přímo:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Požadavky na sladění pro poisoning AddressSanitizer
Jakékoli ruční poisoning stínových bajtů musí vzít v úvahu požadavky na zarovnání. Uživatel musí v případě potřeby přidat odsazení, aby stínové bajty skončily na hranici bajtů ve stínové paměti. Každý bit ve stínové paměti AddressSanitizer kóduje stav jednoho byte v paměti aplikace. Toto kódování znamená, že celková velikost každého přidělení včetně odsazení musí být zarovnána na hranici 8 bajtů. Pokud není splněn požadavek na sladění, může to vést k nesprávnému hlášení chyb. Nesprávné hlášení se může projevit jako chybějící sestavy (falešně negativní výsledky) nebo sestavy o jiných chybách (falešně pozitivní).
Obrázek požadavku na sladění a potenciálních problémů najdete v uvedených příkladech sladění ASan. Jedním z nich je malý program, který ukáže, co se pokazí ručním poškozením stínové paměti. Druhým je příklad implementace ručního poisoningu pomocí std::allocator rozhraní .
Možnosti za běhu
Microsoft C/C++ (MSVC) používá modul runtime založený na modulu runtime Clang AddressSanitizer z úložiště llvm-project. Z tohoto důvodu se většina možností modulu runtime sdílí mezi těmito dvěma verzemi. Úplný seznam možností veřejného modulu runtime jazyka Clang je k dispozici tady. Některé rozdíly zdokumentováme v následujících částech. Pokud zjistíte možnosti, které nefunguje podle očekávání, nahlásit chybu.
Nepodporované možnosti AddressSanitizer
- detect_container_overflow
- unmap_shadow_on_exit
Poznámka
Možnost modulu runtime AddressSanitizer halt_on_error nefunguje tak, jak byste očekávali. V knihovnách Clang a MSVC runtime se mnoho typů chyb považuje za nepřetržitelné ,včetně většiny chyb poškození paměti.
Další informace najdete v části Differences with Clang 12.0.
MSVC konkrétních možností modulu runtime AddressSanitizer
windows_hook_legacy_allocatorsLogická hodnotatruenastavená na povolí zachycení aGlobalAllocLocalAllocalokátorů.
Poznámka
Možnost nebyla při napsání tohoto článku dostupná ve veřejném modulu windows_hook_legacy_allocators runtime llvm-project. Možnost může nakonec přispět zpět do veřejného projektu. Závisí ale na revize kódu a přijetí komunitou.
Ve výchozím nastavení je teď povolená možnost , která byla dříve funkcí výslovného souhlasu, zatímco windows_hook_rtl_allocators addressSanitizer byla experimentální.
Seznam zachycovaných funkcí AddressSanitizer (Windows)
Hot AddressSanitizer runtime – opravují mnoho funkcí, které umožňují kontrolu bezpečnosti paměti za běhu. Zde je nevyčerpávající seznam funkcí, které modul runtime AddressSanitizer monitoruje.
Výchozí zachycení
- (jenom x64)
_aligned_free_aligned_malloc_aligned_msize_aligned_realloc_calloc_base_calloc_crt- (pouze ladění za běhu)
- (jenom x86)
- (jenom x86) (nedokumentované)
_expand_expand_basenedokumentovanými- (pouze ladění za běhu)
_free_basenedokumentovanými- (pouze ladění za běhu)
_malloc_basenedokumentovanými_malloc_crtnedokumentovanými- (pouze ladění za běhu)
_msize_msize_basenedokumentovanými- (pouze ladění za běhu)
_realloc_basenedokumentovanými_realloc_crtnedokumentovanými- (pouze ladění za běhu)
_recalloc_recalloc_basenedokumentovanými_recalloc_crtnedokumentovanými- (pouze ladění za běhu)
_strdupatoiatolcallocCreateThreadfreefrexplongjmpmallocmemchrmemcmpmemcpymemmovememsetRaiseExceptionreallocRtlAllocateHeapRtlCreateHeapRtlDestroyHeapRtlFreeHeapRtlRaiseExceptionRtlReAllocateHeapnedokumentovanýmiRtlSizeHeapnedokumentovanýmiSetUnhandledExceptionFilterstrcatstrchrstrcmpstrcpystrcspnstrdupstrlenstrncatstrncmpstrncpystrnlenstrpbrkstrspnstrstrstrtokstrtolwcslenwcsnlen
Volitelné zachycení
Zachycené moduly, které jsou tady uvedené, se nainstalují jenom v případě, že je povolená možnost AddressSanitizer runtime. Nastavte windows_hook_legacy_allocators na true , aby se povolilo starší zachycení přidělování.
set ASAN_OPTIONS=windows_hook_legacy_allocators=true
GlobalAllocGlobalFreeGlobalHandleGlobalLockGlobalReAllocGlobalSizeGlobalUnlockLocalAllocLocalFreeLocalHandleLocalLockLocalReAllocLocalSizeLocalUnlock
Viz také
AddressSanitizer – přehled
AddressSanitizer známé problémy
Reference k sestavení a jazyku AddressSanitizer
AddressSanitizer stínové bajty
AddressSanitizer Cloud nebo distribuované testování
Integrace ladicího programu AddressSanitizer
Příklady chyb AddressSanitizer