Unlike stack memory which grows downward from high addresses and is automatically managed via function call frames, Heap memory grows upward from lower addresses and is managed explicitly at runtime via dynamic allocation.
Understanding heap layout and allocator metadata is fundamental to analyzing heap exploitation primitives (such as use-after-free, heap overflows, fastbin dupes, and unlink exploitation).
Core Allocation Primitives
malloc(size): Requestssizebytes from the heap and returns a generic pointer. The returned memory is uninitialized.calloc(num, size): Allocates memory for an array and initializes all bytes to zero (mitigates information disclosure bugs).realloc(ptr, size): Resizes an existing heap block, either expanding in-place or allocating a new region, copying existing data, and freeing the old chunk.free(ptr): Releases the allocated chunk back to the heap manager.
Kernel Interface: brk/sbrk vs. mmap
The userspace memory allocator (e.g., Glibc’s ptmalloc) interacts with the Linux kernel using two primary system calls:
brk/sbrk: Adjusts the process “program break” pointer to expand or contract the contiguous heap segment. Used for smaller dynamic allocations.mmap: Maps an anonymous private page directly into the process address space. Allocations exceedingMMAP_THRESHOLD(typically 128 KB) bypass the contiguous heap segment entirely and receive a dedicatedmmapallocation.
ptmalloc Chunk Internal Architecture
In Glibc’s ptmalloc (derived from Doug Lea’s dlmalloc), dynamic memory is organized into chunks.
1. Allocated Chunk Layout
When memory is in active use by the application:
+-----------------------+-----------------------+
| prev_size | size | A | M | P
+-----------------------+-----------------------+
| User Data ... |
| |
+-----------------------------------------------+
prev_size: If the immediately preceding contiguous chunk is free, this field holds its size (used during coalescing).size: Total chunk size (aligned to 8 bytes on 32-bit systems, 16 bytes on 64-bit systems).- Flag Bits (Lowest 3 bits of
size):P(PREV_INUSE,0x1): Set to1if the previous chunk is allocated;0if free.M(IS_MMAPPED,0x2): Set if allocated viammap.A(NON_MAIN_ARENA,0x4): Set if chunk originates from a secondary thread arena.
2. Free Chunk Layout
When a chunk is freed, its user data area is repurposed to link it into allocation lists (bins):
+-----------------------+-----------------------+
| prev_size | size | A | M | P
+-----------------------+-----------------------+
| *fd (Forward Pointer) |
+-----------------------------------------------+
| *bk (Backward Pointer) |
+-----------------------------------------------+
| fd_nextsize / bk_nextsize (Large bins) |
+-----------------------------------------------+
| ... |
+-----------------------------------------------+
| size (duplicate at footer) |
+-----------------------------------------------+
fd/bk: Doubly linked list pointers pointing to neighbor free chunks in the bin.
Bins and Free Lists
When free() is called, chunks are placed into specialized bins categorized by size to optimize re-allocation speed:
- Fastbins: Singly linked LIFO lists for small allocations (< 80 bytes). Chunks in fastbins do not have their
PREV_INUSEbit cleared to avoid immediate coalescing overhead. - Unsorted Bin: Temporary transit queue where chunks first arrive upon being freed, facilitating fast reuse.
- Small Bins: Fixed-size doubly linked lists (< 512 bytes on 32-bit, < 1024 bytes on 64-bit).
- Large Bins: Variable-size doubly linked sorted lists for larger allocations.
- Tcache (Thread Local Caching): Per-thread singly linked lists introduced in modern Glibc to eliminate lock contention in multithreaded applications.
Comparative Modern Allocators
- ptmalloc3: Default in standard Glibc. Uses thread arenas to minimize multi-threaded lock contention.
- tcmalloc (Google): Thread-Caching Malloc designed for extreme high-concurrency workloads and built-in heap profiling.
- jemalloc (FreeBSD / Meta): Focuses on predictable fragmentation avoidance; default in FreeBSD and used heavily by Firefox and Redis.