/* We overlay this structure on the user-data portion of a chunk when
the chunk is stored in the per-thread cache. */typedefstruct tcache_entry
{
struct tcache_entry *next;
} tcache_entry;
/* There is one of these for each thread, which contains the
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */typedefstruct tcache_perthread_struct
{
char counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
static __thread tcache_perthread_struct *tcache = NULL;

$ ./tcache_house_of_spirit
We will overwrite a pointer to point to a fake 'smallbin' region.
The chunk: 0x7fffffffdb00
Overwritting our pointer with the address of the fake region inside the fake chunk, 0x7fffffffdb00.
Freeing the overwritten pointer.
Now the next malloc will return the region of our fake chunk at 0x7fffffffdb00, which will be 0x7fffffffdb10!
malloc(0x100): 0x7fffffffdb10

$ ./tcache_poisoning
Our target is a stack region at 0x7fffffffdcc0
Allocated victim chunk with requested size 0x30 at 0x555555756670
Freed victim chunk to put it in a tcache bin
Emulating corruption of the next ptr
Now we make two requests for the appropriate size so that malloc returns a chunk overlapping our target
The first malloc(0x30) returned 0x555555756670, the second one: 0x7fffffffdcc0