Buffer underwrite¶
Bir buffer'ın başının öncesine yaz; negatif bir index ya da base'inin altına decrement edilmiş bir pointer üzerinden (CWE-124).
Mechanism¶
Note
CWE-124 (Buffer Underwrite / "Buffer Underflow"): "Ürün, buffer'ın başlangıcından önceki bir memory konumuna referans veren bir index ya da pointer kullanarak bir buffer'a yazar." Bu "bir pointer ya da index'i buffer'dan önceki bir konuma decrement edildiğinde, pointer arithmetic geçerli memory konumunun başlangıcından önceki bir konumla sonuçlandığında ya da negatif bir index kullanıldığında" olur.
Invariant — under-read ile aynı kök ama çok daha tehlikeli olan write yolunda. Store, programın değiştirmeyi amaçlamadığı memory'ye düşer. MITRE: bu "büyük olasılıkla ilgili memory'nin ve belki instruction'ların corruption'ı ile sonuçlanır, muhtemelen bir crash'e yol açar. Corrupt olmuş memory etkili biçimde kontrol edilebilirse, arbitrary code çalıştırmak mümkün olabilir." Klasik bir tetikleyici, sonlandırma koşulu atlanabilen ve index'i 0'ın altına yürüten geriye dönük tarayan bir loop'tur.
Walkthrough¶
MITRE'nin trimTrailingWhitespace örneğine dayanarak — tamamen whitespace olan
bir input loop'u buffer'ın altına sürer:
char *trimTrailingWhitespace(char *strMessage, int length) {
char *message = malloc(length + 1);
int index;
for (index = 0; index < length; index++) // copy input into buffer
message[index] = strMessage[index];
message[index] = '\0'; // after loop index == length
int len = index - 1; // last char index
while (isspace(message[len])) { // BUG: no len >= 0 guard
message[len] = '\0'; // underwrite when len goes negative
len--;
}
return message;
}
Beklenen davranış: input tamamen whitespace ise loop hiç non-space bir char
bulamaz; bu yüzden len 0'ı geçerek decrement olur ve message[len] = '\0'
buffer'ın öncesindeki memory'ye NUL byte'ları yazar — komşu data/metadata'yı
corrupt eder. Kontrol edilebilir bir target ile bu bir
arbitrary write haline gelir; aksi halde crash
eder. Heap'te, önceki bir chunk'ın metadata'sına underwrite yapmak allocator
ataklarını besler (off-by-null poison,
unsafe unlink).
Detection¶
- AddressSanitizer redzone'ları underflow write'ı işaretler.
- Static analysis, lower-bound guard'ı olmayan decrement eden loop index'lerini işaretler.
Mitigation¶
- Geriye dönük loop'ları
len >= 0ile koru. - Herhangi bir indexed store'dan önce
0 <= index < len'i doğrula. - Stack canary'leri / heap metadata hardening bazı downstream corruption'ı yakalar, ama asıl fix bounds check'tir.