layout: post title: "title" subtitle: "ptmalloc" date: 2019-05-07 09:17:52 author: "none" header-img: "img/posts/default_post.jpg" catalog: true tags: - tag
https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/
main thread: main arena (sbrk alloc)
thread: thread arena (mmap alloc)
thread arena 的数量和操作系统位数和cpu核数有关, 线程太多时需要竞争使用thread arena
malloc_state:Arena Header, Arena header contains information about bins, top chunk, last remainder chunk
heap_info: 一个thread arena可以有多个heap, 每个heap由heap_info来标识; Main arena没有多个heap,没有heap_info
malloc_chunk:一个heap由多个malloc_chunk构成
前一个chunk(低地址), 后一个chunk(高地址)
/* addressing -- note that bin_at(0) does not exist */
#define bin_at(m, i) \
(mbinptr) (((char *) &((m)->bins[((i) - 1) * 2])) \
- offsetof (struct malloc_chunk, fd))
/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
#define unsorted_chunks(M) (bin_at (M, 1))
地址转换
MALLOC_ALIGN_MASK malloc的chunk块大小应该进行对齐(malloc_chunk的size字段低三位不可用,因此需要对齐)
fastbin
fastbin 由多个bin构成,每个bin是一个链表,将相同大小的chunk串起来 idx = fastbin_index (nb); //从需要分配的大小获得相应的bin索引
从fastbin找到可分配的malloc chunk后, 会检查该malloc chunk的header信息(chunk 的size) 是否为bin的大小, 如果不是说明该malloc chunk被其他地方写过, 触发内存破坏"malloc(): memory corruption (fast)" if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0)) { errstr = "malloc(): memory corruption (fast)"; errout: malloc_printerr (check_action, errstr, chunk2mem (victim)); return NULL; }
流程
malloc.c
__libc_malloc
void *weak_variable (*__malloc_hook)
(size_t __size, const void *) = malloc_hook_ini;
hook.c
static void *
malloc_hook_ini (size_t sz, const void *caller)
{
__malloc_hook = NULL;
ptmalloc_init ();
return __libc_malloc (sz);
}
arena.c
ptmalloc_init
arena_lookup (ar_ptr); // 找到一个可用的arena,并加锁 victim = _int_malloc (ar_ptr, bytes); // 从该arena中寻找malloc chunk
_int_malloc checked_request2size (bytes, nb); // 分配内存大小转换 if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ())) // 从fastbin中分配内存, if (in_smallbin_range (nb)) // 从smallbin中分配内存