tcmalloc Insert to FreeList[X]¶
Klasik "4-to-N byte overflow" primitive'ini tcmalloc'ta diriltmek: freed bir object'in ilk word'üne yapılan minik bir overflow, bir size-class free list head'ini yeniden yönlendirir, böylece o class'ın sonraki allocation'ı attacker'ın etkilediği bir region döndürür — yalnızca ~4 byte'lık bozulmanın mevcut olduğu yerde kontrollü bir N-byte write.
Mechanism¶
Note
tcmalloc her size class için per-thread (veya per-CPU) bir FreeList tutar. Free
object'ler freed region'ının ilk word'ü üzerinden singly linked'tir ve list head
cache yapısında yaşar. Pop yolu (SLL_Pop) kasten minimaldir: Sean Heelan'ın orijinal
Infiltrate-2011 analizi, *list pointer'ının değeri üzerinde "herhangi bir türden check
olmadığını" vurgular — span-membership testi yok, alignment yok, freed-state cookie'si yok.
Burada aşılan sınır,
../primitive/tcmalloc-arbitrary-address-return.md
ile aynı güvendir — next word'ünün allocator tarafından yazıldığı varsayılır — ama
kaldıraç farklıdır ve bu primitive'i dikkat çekici kılan şey budur. Yalnızca küçük
bir overflow'a izin veren bir güvenlik açığı (komşu freed bir chunk'ın forward pointer'ının
kanonik "4-byte" overwrite'ı) bir N-byte overflow'a dönüştürülür: forge edilmiş bir
node ekleyerek list head'in attacker'ın seçtiği bir adresi göstermesini sağlayınca, size
class X'in sonraki allocation'ı o region'ı döndürür ve uygulamanın taze "allocated"
object'e kendi write'ı, attacker'ın hedefinde keyfi uzunlukta bir write hâline gelir.
Heelan bunu, hardening'in başka yerlerde öldürdüğü ama eksik integrity check'leri yüzünden
tcmalloc'ta hayatta kalan Windows-XP dönemi "Insert to Lookaside" etkisini geri getirmek
olarak çerçeveledi.
Walkthrough¶
Yüksek seviyeli, Heelan (2011) ve Jardin (2025) revival'ından — yalnızca kavramsal:
-
Küçük bir overflow bul. Bir bug, bir allocation'ın birkaç byte ötesine, aynı size class'tan komşu bir freed object'e overwrite yapmaya izin verir — o object'in ilk word'ünü (
next/forward pointer'ını) ezmeye yetecek kadar. -
List head'i yeniden yönlendir. Forward pointer'ı overwrite etmek "list head'i kontrol ettikleri bir adrese yeniden yönlendirir", yani
FreeList[X]'e forge edilmiş bir node enjekte eder. Pop sırasında heap dışı pointer'ı reddeden bir validation yoktur.
/* victim B is freed and sits in FreeList[X]; A is the overflow source */
free(B); /* FreeList[X] head -> B -> ... */
/* small (~ptr-width) overflow from A clobbers B.next */
*(void **)B = (void *)target; /* B.next = chosen address */
malloc(X); /* pops B */
void *p = malloc(X); /* pops 'target' -> attacker region */
/* the program's normal write into p is now an N-byte write at target */
- N-byte write'ı uygulamaya yaptır. Döndürülen object normal bir allocation olarak
ele alındığından, uygulamanın ona yazdığı her şey (ki orijinal 4-byte overflow'dan çok daha
büyük olabilir)
target'a düşer.
4-to-N amplification
Tanımlayıcı özellik: bozulma kapasitesi ile write kapasitesi birbirinden ayrılır. List metadata'sının tek bir pointer'lık overwrite'ı, tam boyutlu attacker-controlled bir allocation verir, yani etkin write genişliği orijinal bug ile değil size class ile sınırlanır — tam olarak Phrack dönemi lookaside overflow'larının Windows XP'de verdiği amplification.
Warning
Public writeup'lardan pratik kısıtlar: forge edilmiş region genellikle asla free()'ye
ulaşmamalıdır (non-heap bir pointer'ı free etmek crash verir) ve kullanışlı, güvenilir
şekilde konumlanmış bir target seçmek için tipik olarak bir memory leak gerekir.
Per-CPU tcmalloc, poisoned list ile takip eden allocation'ların aynı cache'i paylaşması
için CPU pinning gerektirir.
Detection¶
- ASan / debug allocator. Forge edilmiş head pop edilmeden önce, komşu-object overflow'unu bozulma noktasında yakalar.
- Wild-pointer allocation'lar. Class X'in unaligned bir adres veya sahip olunan herhangi
bir span'in dışındaki bir adres döndüren
malloc'u, enjekte edilmiş bir FreeList node'una işaret eder. - Grooming imzaları. Freed bir victim'i list head'ine konumlandırmak için yapılan yoğun same-size-class alloc/free churn'ü, allocation profiler'larında görünür.
- Heap canary'leri / redzone'lar. Inter-object redzone'lar (desteklendiği yerde) komşunun metadata'sına yapılan küçük overflow'u işaretler.
Mitigation¶
- tcmalloc'u yükselt / integrity check'lerini etkinleştir. Modern release'ler pop edilen
object'lerin sahip olan span'e ait olduğunu doğrular ve forge edilmiş bir
next'te abort eden sanitizing build'ler sunar — Heelan'ın istismar ettiği "*list'te check yok" boşluğunu doğrudan kapatır. - Per-CPU front-end'i tercih et, ki bu cross-span forge edilmiş pointer'ları zorlaştırır.
- Attacker'ın erişebileceği buffer'ları taşıyan size class'lar için inter-allocation redzone'lar / guard page'ler ekle, böylece küçük overflow yakalanır.
- Kök overflow'u düzelt: ../primitive/heap-buffer-overflow.md / ../primitive/controlled-size-allocation.md — hassas komşuluğu mümkün kılan grooming.