Skip to main content

Overview

The heap is a region of memory used for dynamic memory allocation. Unlike stack memory, which grows and shrinks automatically with function calls, heap memory must be explicitly allocated and freed by the programmer using functions like malloc() and free().

glibc malloc Implementation

The GNU C Library (glibc) malloc is the default memory allocator on most Linux systems. It manages heap memory efficiently by organizing freed memory into different bins based on size and reusing previously allocated chunks.
Understanding glibc malloc internals is crucial for heap exploitation, as many vulnerabilities arise from the allocator’s behavior.

Chunk Structure

Every allocation in glibc malloc is represented as a chunk. A chunk contains metadata along with the user data:

Key Points

  • prev_size: Stores the size of the previous chunk if it’s free
  • size: Contains the chunk size and three flag bits (P, M, N)
  • fd/bk: Forward and backward pointers form doubly-linked lists of free chunks
  • User data: Overlaps with fd/bk when the chunk is allocated
The fd and bk pointers are stored in the same memory location as user data when a chunk is allocated. This is why use-after-free vulnerabilities can be so dangerous.

Bin Types

glibc malloc organizes free chunks into different “bins” - data structures that hold freed chunks for efficient reuse.
1

tcache (Thread Cache)

  • Size range: Small allocations (up to 1032 bytes on 64-bit)
  • Structure: Singly-linked list per thread
  • Count: 64 bins, one per size class
  • Max chunks: 7 chunks per bin (default)
  • Performance: Fastest, no thread locking needed
Introduced in glibc 2.26, tcache is checked first before other bins.
2

fastbins

  • Size range: 16-80 bytes (64-bit), 8-64 bytes (32-bit)
  • Structure: Singly-linked list (LIFO)
  • Count: 10 bins
  • Coalescing: Chunks are NOT merged with adjacent free chunks
  • Performance: Fast, but slower than tcache
3

smallbins

  • Size range: Less than 1024 bytes (64-bit)
  • Structure: Doubly-linked list (FIFO)
  • Count: 62 bins
  • Coalescing: Chunks ARE merged with adjacent free chunks
  • Exact fit: Each bin contains one specific size
4

largebins

  • Size range: 1024 bytes and larger (64-bit)
  • Structure: Doubly-linked list sorted by size
  • Count: 63 bins
  • Coalescing: Chunks ARE merged with adjacent free chunks
  • Size range: Each bin contains a range of sizes
5

unsorted bin

  • Purpose: Temporary storage for recently freed chunks
  • Structure: Single doubly-linked list
  • Count: 1 bin
  • Behavior: Chunks are sorted into appropriate bins on next malloc

Allocation Mechanics

When you call malloc(size), glibc follows this allocation strategy:
1

Check tcache

If tcache has a chunk of the requested size, return it immediately.
2

Check fastbins

If the size fits a fastbin and one exists, return the head chunk.
3

Small request

For small sizes, check the corresponding smallbin. If empty, check unsorted bin.
4

Large request

For large sizes, check largebins using best-fit or exact-fit search.
5

Top chunk

If no suitable chunk found, split off memory from the top chunk (wilderness).
6

Extend heap

If top chunk is too small, extend the heap using sbrk() or mmap().

Free Mechanics

When you call free(ptr), glibc performs several operations:
1

Validation

Check if the pointer and chunk metadata are valid.
2

tcache insertion

If tcache for this size isn’t full, add the chunk and return.
3

Fastbin insertion

If the size fits fastbin range, add to the appropriate fastbin (LIFO).
4

Coalescing

Merge the chunk with adjacent free chunks (backward and forward).
5

Unsorted bin

Place the consolidated chunk in the unsorted bin.
6

Top chunk merge

If the freed chunk is adjacent to the top chunk, merge it back.
Coalescing is disabled for fastbins and tcache, making them faster but also creating opportunities for exploitation.

Size Calculations

The actual chunk size differs from the requested size:

Key Concepts for Exploitation

Many heap exploits rely on understanding these fundamental behaviors:
  • First-fit allocation: malloc reuses the first suitable free chunk
  • Use-after-free: Freed memory retains pointers (fd/bk) that overlap with user data
  • Chunk coalescing: Adjacent free chunks are merged (except fastbins/tcache)
  • Metadata corruption: Overwriting chunk headers can hijack control flow
  • Bin manipulation: Corrupting bin lists can cause malloc to return arbitrary addresses

Next Steps

Malloc Playground

Interactive tool to experiment with allocations

First Fit

Understanding first-fit allocation strategy

tcache Index

How tcache indices are calculated

Techniques

Explore heap exploitation techniques