if (ar_ptr != NULL) __libc_lock_unlock (ar_ptr->mutex);
/* In a low memory situation, we may not be able to allocate memory - in which case, we just keep trying later. However, we typically do this very early, so either there is sufficient memory, or there isn't enough memory to do non-trivial allocations anyway. */ if (victim) { tcache = (tcache_perthread_struct *) victim; memset (tcache, 0, sizeof (tcache_perthread_struct)); }
➜ calc ./calc_tca This file doesn't demonstrate an attack, but calculates the tcache idx for a given chunk size. The basic formula is as follows: IDX = (CHUNKSIZE - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT On a 64 bit system the current values are: MINSIZE: 0x20 MALLOC_ALIGNMENT: 0x10 So we get the following equation: IDX = (CHUNKSIZE - 0x11) / 0x10
BUT be AWARE that CHUNKSIZE is not the x in malloc(x) It is calculated as follows: IF x + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE(0x20) CHUNKSIZE = MINSIZE (0x20) ELSE: CHUNKSIZE = (x + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) => CHUNKSIZE = (x + 0x8 + 0xf) & ~0xf
[CTRL-C to exit] Please enter a size x (malloc(x)) in hex (e.g. 0x10): 0x10
TCache Idx: 0 [CTRL-C to exit] Please enter a size x (malloc(x)) in hex (e.g. 0x10): 0x25
TCache Idx: 1 [CTRL-C to exit] Please enter a size x (malloc(x)) in hex (e.g. 0x10): 0x23
TCache Idx: 1 [CTRL-C to exit] Please enter a size x (malloc(x)) in hex (e.g. 0x10): 0x40
TCache Idx: 3 [CTRL-C to exit] Please enter a size x (malloc(x)) in hex (e.g. 0x10):
// #if USE_TCACHE { size_t tc_idx = csize2tidx (size); if (tcache != NULL && tc_idx < mp_.tcache_bins) { /* Check to see if it's already in the tcache. */ tcache_entry *e = (tcache_entry *) chunk2mem (p);
/* This test succeeds on double free. However, we don't 100% trust it (it also matches random payload data at a 1 in 2^<size_t> chance), so verify it's not an unlikely coincidence before aborting. */ if (__glibc_unlikely (e->key == tcache)) { tcache_entry *tmp; LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); for (tmp = tcache->entries[tc_idx]; tmp; tmp = tmp->next) if (tmp == e) malloc_printerr ("free(): double free detected in tcache 2"); /* If we get here, it was a coincidence. We've wasted a few cycles, but don't abort. */ }