tcmalloc Arbitrary Address Return¶
Bir tcmalloc size-class free list'indeki free edilmiş bir objenin
nextlink'ini (overflow, UAF ya da double free üzerinden) corrupt ederek, allocator'ın sonraki birmalloc'a attacker'ın seçtiği bir adresi vermesini sağlamak — tcmalloc'un fastbin-dup / tcache poisoning analoğu.
Mechanism¶
Note
tcmalloc, her küçük size class'ı, head'i (thread- veya CPU-local) bir
cache yapısında yaşayan ve link'leri free edilmiş objelerin kendi içinde
yaşayan bir singly-linked free list'ten servis eder — bir free region'ın
ilk word'ü onun next pointer'ıdır. Allocator'ın pop yolu (SLL_Pop ve
arkadaşları) bu next word'ünün, kendisinin yazdığı bir list link'i olduğuna
güvenir: head'i okur, head'i head->next olarak ayarlar ve eski head'i
döndürür. next'in allocator'ın sahip olduğu bir span'e işaret ettiğine
dair bir doğrulama yoktur, alignment kontrolü yoktur ve freed-state cookie'si yoktur.
İhlal edilen invariant şudur: "bir free objenin next word'ü allocator
tarafından yazıldı ve yalnızca aynı list'teki başka bir free objeyi gösterir."
Bir attacker o word'ü yazarsa — free edilmiş bir komşuya overflow ederek, bir
dangling pointer'ı dereference ederek ya da aynı objeyi iki kez free ederek —
list zehirlenir. ArcHeap yazarlarının ifadesiyle, free edilmiş bir chunk'ı
corrupt etmek şu anlama gelir: "allocations will remove a chunk from list and
set the list head, finally leading to modifying the head. Then, the next
allocation will return a corrupted memory address, which is controlled by
attackers." Bunun "analogous to fast-bin-dup in ptmalloc" olduğunu belirtirler.
tcmalloc, ptmalloc'un sonradan eklediği freed-chunk güvenlik kontrollerini
atladığından, sade bir double free bile allocation'ları doğrudan duplicate eder.
Walkthrough¶
Üst düzey; ArcHeap PoC'sini (§A, "arbitrary address return") yansıtır — tıpkı
../primitive/tcache-poisoning.md gibi bir free objenin ilk
word'ü üzerinden link verir:
/* all same size class S, served by one singly-linked FreeList */
void *a = malloc(S);
void *b = malloc(S);
free(b); /* FreeList head -> b -> ... */
free(a); /* FreeList head -> a -> b -> ... */
/* overflow / UAF / double-free lets us rewrite the head object's next word */
*(void **)a = (void *)target; /* a.next = target (no validation in SLL_Pop) */
malloc(S); /* pops a */
void *x = malloc(S);/* pops 'target' -> attacker-chosen ptr */
/* x now aliases attacker-controlled memory -> arbitrary write */
- Hedef size class'ı groom et ki victim objeler onun free list'inin head'inde otursun.
- Bug'ı (free edilmiş komşuya overflow / UAF / double free) kullanarak head
objenin ilk word'ünü
targetile overwrite et. - Meşru head'i geçecek kadar drain etmek için allocate et; sonraki
malloctargetdöndürür. - Döndürülen pointer üzerinden yazmak
target'ta bir arbitrary write verir.
Neden hiçbir kontrol tetiklenmez
Herkese açık PoC'ler, corrupt edilmiş pointer'ın hayatta kaldığını vurgular; çünkü front-end pop yolu hiçbir span-üyeliği ya da alignment testi yapmaz. Tekniğe ait ArcHeap kaynak yorumu "tcmalloc has a next chunk address at the end of a chunk" der ve doğrudan o link'e dayanır. Corrupt edilmiş objeyi thread/CPU cache'inin içinde tutmak (objelerin index'lerini izleyen central free list'e flush olmasına izin verme) exploitation'ı güvenilir tutar.
Warning
Güvenilirlik cache locality'sine bağlıdır. Modern per-CPU tcmalloc'ta
front-end çalışan CPU'ya göre anahtarlanır, dolayısıyla free'ler ve devam
eden allocation'lar aynı mantıksal CPU'ya düşmelidir — thread'i sabitle
(örneğin sched_setaffinity). Hardened/sanitize edilmiş build'ler,
zehirlenmiş ya da double-free edilmiş bir link'te abort eden freelist
integrity kontrolleri ekler.
Detection¶
- ASan / allocator debug build'leri. AddressSanitizer ile ya da tcmalloc'un debug/sanitize modlarıyla derlemek, double-free'yi ve free edilmiş objeye yapılan out-of-bounds write'ı corruption anında yakalar.
- Crash forensics. Hizasız bir pointer ya da sahip olunan herhangi bir
span'in dışındaki bir pointer döndüren bir
malloc, güçlü bir list-poisoning işaretidir; wild bir head pointer'ı ile front-end pop yolundaki çökmeler bu primitive'e işaret eder. - Allocation telemetrisi. Aynı-size-class alloc/free çiftlerinin patlamaları (grooming) ve aynı adresin tekrarlı free'leri, allocation profiler'larında gözlemlenebilir.
- Guarded reuse. Free edilmiş bellek poison/quarantine doldurması (etkin olduğunda), bir attacker geri dönüştürülmüş bir region'ı sondaladığında fault verir.
Mitigation¶
- Güncel tcmalloc / per-CPU front-end kullan. Modern release'ler, pop edilen bir objenin sahip olan span'e ait olduğunu doğrular ve per-CPU cache'i tercih eder, naif cross-span forge edilmiş pointer'ları kırar.
- Sunan build'lerde freelist integrity / sanitizer desteğini etkinleştir ki
corrupt edilmiş ya da duplicate edilmiş bir
nextonurlandırılmak yerine abort etsin. - Besleyen bug sınıfını ortadan kaldır: free edilmiş objelere ../primitive/double-free.md, ../primitive/use-after-free.md ve ../primitive/heap-buffer-overflow.md.