Skip to content

Global/BSS buffer overflow

.data/.bss içindeki bir global ya da static buffer'ın ötesine out-of-bounds write yaparak komşu global state'i corrupt etme.

Mechanism

Bir global veya file-static buffer, main() çalışmadan önce allocate edilen .data (initialized) ya da .bss (zero-initialized) segment'inde yaşar — heap'te değil ve malloc() ile değil. Sınırlarının ötesine yazmak, komşu globaller'e yapılan bir out-of-bounds write'tır (CWE-787/CWE-788); komşu global state'i, function pointer'ları veya kaydedilmiş data'yı corrupt edebilir.

Note

Bu, heap-buffer-overflow'tan (CWE-122) kategorik olarak farklıdır: depolama, allocator tarafından yönetilen chunk'lar değil, link zamanında yerleştirilen static program memory'sidir. Komşuluk bu yüzden bir runtime allocator tarafından değil linker tarafından belirlenir; bu da onu deterministik ama groom etmesi daha zor yapar.

Walkthrough

Microsoft'un ASan dokümantasyonu, global bir array üzerinde out-of-bounds bir index ile bir global-buffer-overflow tetikler:

double x[5];
int main() {
    int rc = (int) x[5];  // Boom! -- reads one element past x[4]
    return rc;
}

cl ... /fsanitize=address ile derlendiğinde AddressSanitizer bir global-buffer-overflow raporlar.

Note

Microsoft'un minimal örneği bir out-of-bounds read'i gösterir (x[5] okunur). ASan'ın global-buffer-overflow sınıfı hem out-of-bounds read hem de write erişimlerini kapsar; redzone'a düşen herhangi bir access raporlanır. Bu primitive'in esas corruption yönü ise write'tır — örn. x[5] = ... komşu bir global'i bozar. Örnek, sadece redzone tespitini tetiklemenin en kısa yolu olduğu için okuma kullanır.

Aynı doküman file-static ve function-static varyantlarını da kapsar. Compiler'lar ".data veya .bss section'larındaki herhangi bir değişken için metadata üretir … main() başlamadan önce memory'de allocate edilir" ve C, aynı global'in translation unit'ler arasında farklı tip/boyutlarla tanımlanmasına izin verdiğinden (linker en büyüğünü seçer), ASan object-file link sırasından bağımsız olarak access anında raporlar.

Warning

COMMON section'ına yerleştirilen uninitialized globaller için ASan redzone ekleyemez, bu yüzden onları instrumentation için doğru .bss'e taşımak adına GCC'nin -fno-common'ı gerekir.

Detection

AddressSanitizer global object'lerin etrafına poisoned redzone'lar yerleştirir; bir redzone'a düşen bir access (shadow byte 0xf9) global-buffer-overflow olarak raporlanır. -fno-common uninitialized globaller'i instrument edilebilir kılar.

Mitigation

Index'leri ve uzunlukları bounds-validate et; test sırasında ASan ile derle (artı -fno-common); fortified string/mem fonksiyonları için _FORTIFY_SOURCE; sabit boyutlu global buffer'lara unbounded copy'lerden kaçın.

References