The art of exploiting heap overflow, part 4
The art of exploiting heap overflow, part 4
ptmalloc2 overview
From kernel’s point of view, heap is just some dynamic anonymous memory mappings. It is hard to track and manage without more abstractions on top.
Therefore, ptmalloc2 abstracts it as a hierarchy with 3 layers to manage the whole heap. Many existing articles on Internet don’t explain them clearly. They are simpler than what you actually think.
struct malloc_state
heap_info
struct malloc_chunk
So, the internal heap is still confusing, right? Let’s take a look at an arena which contains two internal heaps:
The first internal heap contains both a heap_info header and an arena header, this is due to that it is allocated (with mmap()) together with this arena. But a second one is added when we can’t satisfy an allocation request from the first internal heap, so now this arena has to expand by adding a new internal heap with mmap() and links it with the previous one, the arena is able to manage both now.
Main arena is again different, its header does not resident in an internal heap, instead it is statically defined in glibc code as main_arena.
static struct malloc_state main_arena ={ .mutex = _LIBC_LOCK_INITIALIZER, .next = &main_arena, .attached_threads = 1};
It just points to the sbrk()’ed memory arena obtained via sbrk(0), that is the traditional heap. It only grows by sbrk() so can’t have any internal heap.
sbrk(0)
If we put it into the whole picture, it is:
Now we can see, the internal heap is, in fact, somehow not a middle layer but a thin auxiliary layer. Arenas don’t use internal heaps to manage the memory chunks inside, they are still directly responsible to manage all the chunks, which is the most complex part we will cover in the following part.