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
callockullan. - CI'da static analysis ve MSan çoğu vakayı yakalar.