Skip to content

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:

  1. 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.

  2. 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  */
  1. 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.

References