Stínové bajty AddressSanitizer
Stručně shrneme koncept stínových bajtů a způsob jejich použití implementací modulu runtime /fsanitize=address . Další podrobnosti najdete ve sekárním dokumentu a algoritmu AddressSanitizer.
Základní koncept
Každých 8 bajtů ve virtuálním adresové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:
- 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 generování sestav diagnostiky.
Legenda stínového byte
Vezměte v úvahu tuto legendu stínového byte, 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í prostoru aplikace, který je zarovnaný na 0-mod-8, se může namapovat na stínový bajt, který popisuje tento slot ve virtuálním adresové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 konkrétní stínové bajty zapisovat pomocí kódu generovaného kompilátorem, statických dat nebo modulu runtime. Tento pseudokód ukazuje, jak je možné vygenerovat kontrolu, která předchází zatížení nebo uložení:
ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
ReportAndCrash(Addr);
}
Instrumentace odkazu na paměť, který je menší než 8 bajtů, je instrumentace o něco složitější. Pokud je stínová hodnota kladná (to znamená, že je možné získat přístup pouze k prvním kb bajtům v 8bitovém slově), musíme porovnat poslední 3 bity adresy s hodnotou k.
ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
ReportAndCrash(Addr);
}
Modul runtime i kód generovaný kompilátorem zapisují stínové bajty. Tyto stínové bajty buď povolí, nebo odvolí přístup, když se obory ukončí, nebo se úložiště uvolní. Kontroly uvedené výše čtou stínové bajty, které v určité době provádění programu popisují 8 bajtové "sloty" v adresních prostorech vaší aplikace. Kromě těchto explicitně generovaných kontrol modul runtime také kontroluje stínové bajty poté, co zachytí (nebo "zachytí") mnoho funkcí v CRT.
Další informace najdete v seznamu zachycovaných funkcí.
Nastavení stínových bajtů
Kód, který generuje kompilátor, i modul runtime AddressSanitizer mohou zapisovat stínové bajty. Kompilátor může například nastavit stínové bajty tak, aby byl umožněn přístup s pevnou velikostí k místním lokálním hodnotu zásobníku definovaným ve vnitřním oboru. Modul runtime může globální proměnné v oddílu dat ohraničovat stínovým bajtem.
Viz také
Přehled AddressSanitizer
Známé problémy s AddressSanitizerem
Referenční informace k sestavení a jazyku AddressSanitizer
Referenční informace k modulu runtime AddressSanitizer
Cloud AddressSanitizer nebo distribuované testování
Integrace ladicího programu AddressSanitizer
Příklady chyb AddressSanitizer