Stínové bajty AddressSanitizer
Stručně shrneme koncept stínových bajtů a jejich použití implementací modulu runtime /fsanitize=address
. Další podrobnosti najdete v počátečním výzkumu AddressSanitizer - Serebryany, et al a aktuální dokumentaci algoritmu AddressSanitizer.
Základní koncept
Každých 8 bajtů ve virtuálním adresním prostoru aplikace je možné popsat pomocí jednoho stínového bajtu.
Jeden stínový bajt popisuje, kolik bajtů je aktuálně dostupných takto:
- 0 znamená všech 8 bajtů.
- 1-7 znamená jeden až sedm bajtů.
- Záporná čísla kódují kontext modulu runtime, který se má použít pro diagnostiku generování sestav.
Legenda stínového bajtu
Představte si tuto legendu stínového bajtu, kde jsou definována všechna záporná čísla:
Mapování – popis adresního prostoru
Každých 8 bajtů ve virtuálním adresním prostoru aplikace, který je zarovnaný na 0-mod-8, je možné mapovat na stínový bajt, který popisuje tento slot ve virtuálním adresním prostoru. Toto mapování lze provést jednoduchým posunem a přidáním.
Na x86:
char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)
Na x64:
char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)
Generování kódu – testy
Zvažte, jak se můžou zapisovat konkrétní stínové bajty, a to buď kódem vygenerovaným kompilátorem, statickými daty nebo modulem runtime. Tento pseudokód ukazuje, jak je možné vygenerovat kontrolu, která předchází načtení nebo úložišti:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
Při instrumentaci odkazu na paměť, který je menší než 8 bajtů široký, je instrumentace o něco složitější. Pokud je stínová hodnota kladná (což znamená, že k 8bavovým slovům je možné přistupovat pouze první k bajty), musíme porovnat posledních 3 bitů adresy s k.
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
Modul runtime i kód vygenerovaný kompilátorem zapisují stínové bajty. Tyto stínové bajty buď povolí nebo odvolá přístup, když se uvolní obory nebo úložiště. Výše uvedené kontroly čtou stínové bajty, které popisují 8bajtů "slotů" v adresním prostoru vaší aplikace v určitém okamžiku při provádění programu. Kromě těchto explicitně generovaných kontrol modul runtime také kontroluje stínové bajty po zachycení (nebo "háky") mnoho funkcí v CRT.
Další informace najdete v seznamu zachycených funkcí.
Nastavení stínových bajtů
Kód, který kompilátor vygeneruje, i modul runtime AddressSanitizer může zapisovat stínové bajty. Kompilátor může například nastavit stínové bajty, aby umožňoval pevný přístup k místním objektům zásobníku definovaným ve vnitřním oboru. Modul runtime může obklopovat globální proměnné v oddílu dat stínovými bajty.
Viz také
Přehled AddressSanitizer
Známé problémy s addressSanitizerem
Referenční dokumentace k sestavení a jazyku AddressSanitizer
Referenční informace k modulu runtime AddressSanitizer
AddressSanitizer – cloud nebo distribuované testování
Integrace ladicího programu AddressSanitizer
Příklady chyb AddressSanitizer