Skip to content

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 >= 0 ile 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.

References