Skip to content

Access of uninitialized pointer

Bir pointer'ı geçerli bir değer atanmadan önce dereference et; böylece slot'undaki bayat stack/heap içeriği target adres haline gelir (CWE-824).

Mechanism

Note

CWE-824: "Ürün initialize edilmemiş bir pointer'a erişir veya onu kullanır." Uninitialized bir pointer, stack slot'unu veya heap region'ını işgal eden artık byte'ları neyse onu tutar. Program onun üzerinden read, write ya da call yaptığında, target'ı seçen şey geçerli bir object değil, garbage value'dur. MITRE belirtir ki memory layout'a ve allocator davranışına bağlı olarak "attacker uninitialized pointer'ın içeriğini etkileyebilir."

Invariant şu: pointer'ın değeri undefined'dır, ama pratikte undefined ≠ random. Önceki bir fonksiyonun local'leri/argüman'ları, free'lenmiş bir chunk'ın metadata'sı ya da heap-spray'lenmiş bir değer bu slot'u deterministik biçimde işgal edebilir; bu da "undefined"ı "attacker-chosen"a çevirir. MITRE'nin resmi sonuçları:

  • Read memory — bir read'de kullanılır, hassas memory'yi leak eder.
  • DoS — unmapped/NULL memory'ye işaret eder, crash.
  • Execute unauthorized code — bir call'da kullanılır ya da attacker-controlled bir target ile üzerinden write yapılır.

Walkthrough

Slot'unu attacker'ın önceden hazırladığı (prime) uninitialized bir pointer üzerinden write:

void priming(void) {
    char *q = (char *)0x404060;   // attacker value lands in this stack slot
}
void vuln(void) {
    char *p;                       // never initialized -> reuses q's bytes
    /* ... */
    strcpy(p, attacker_data);      // write to 0x404060 (attacker-chosen)
}
int main(void) { priming(); vuln(); }   // same frame depth -> slot reuse

Beklenen davranış: vuln'ün frame'i priming'in az önce bıraktığı stack region'ını yeniden kullandığı için p, 0x404060'ı miras alır; böylece strcpy attacker data'sını seçilen bir adrese yazar — bir arbitrary write. p bunun yerine kötü/NULL bir değer tutarsa process crash olur.

Uninitialized heap pointer varyantı

malloc ile ayrılan ama pointer field'ı hiçbir zaman initialize edilmeyen bir struct, o heap region'ını işgal eden artık byte'ları tutar. Field asla set edilmediğinden (zero'layan calloc değil), attacker heap'i önceden grooming/spray ile hazırlamışsa bu garbage değer attacker-chosen hâline gelebilir; field üzerinden read/call yapmak seçilen adrese gider — bu hâlâ CWE-824'tür (hiç initialize edilmemiş pointer). Buna karşılık field önce set edilip sonra owner free edildiğinde slot'ta kalan bayat değeri kullanmak ayrı bir zafiyettir: bir use-after-free / dangling-pointer dereference'ı (CWE-416/825), bu note'un kapsamı dışında.

Detection

  • Compiler'lar: -Wuninitialized / -Wmaybe-uninitialized, clang -Wsometimes-uninitialized.
  • Runtime: MemorySanitizer (MSan) uninitialized değer kullanımlarını raporlar; Valgrind memcheck undefined data üzerindeki conditional jump/deref'leri işaretler.

Mitigation

  • Pointer'ları declaration'da daima initialize et (= NULL) ve her dereference'i non-NULL koşuluna bağla.
  • Free'lenmiş struct'ların pointer field'larını sıfırla; uygun yerlerde calloc kullan.
  • CI'da static analysis ve MSan çoğu vakayı yakalar.

References