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_allocators Logická hodnota true nastavená na povolí zachycení a GlobalAllocLocalAlloc aloká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í

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

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