Skip to content

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中分配内存