Hacktricks-skills malloc-internals
Understand glibc malloc implementation, heap allocation flow, and memory management internals. Use this skill whenever the user asks about malloc, sysmalloc, heap exploitation, glibc memory allocation, binary exploitation heap challenges, or any questions about how malloc works internally. Trigger for: malloc questions, heap vulnerability research, CTF heap challenges, understanding allocation order, fastbin/smallbin/largebin/tcache behavior, security checks in malloc, or any glibc heap-related topics.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc/SKILL.MDGlibc Malloc Internals
This skill provides comprehensive knowledge about glibc's malloc implementation, including allocation flow, bin management, security checks, and system allocation.
Quick Reference: Allocation Order
When
malloc() is called, glibc follows this decision tree:
- Tcache check → If available chunk of correct size, return it
- Fast bins → Check for exact size match, fill tcache from remaining
- Small bins → Check for exact size match, fill tcache from remaining
- Unsorted bin → First-fit search, split if needed, bin smaller chunks
- Large bins → Best-fit search from current index, then next larger bins
- Top chunk → Split if large enough
- sysmalloc → Request more memory from system
Key Functions
__libc_malloc(bytes)
__libc_malloc(bytes)Entry point for all malloc calls.
What it does:
- Checks tcache first (if enabled)
- Determines if single-threaded or multi-threaded
- Calls
in appropriate arena_int_malloc() - Tags returned pointer with
for securitytag_new_usable()
Key behavior:
- Always tags returned pointers (pointer tagging for security)
- In multi-threaded mode, may retry with different arena if first fails
- Tcache is checked before any other allocation path
_int_malloc(arena, bytes)
_int_malloc(arena, bytes)Main allocation logic that searches all bins.
Flow:
- Convert request size to internal form with
checked_request2size() - If no arena exists, call
directlysysmalloc() - Check fast bins (if size qualifies)
- Check small bins (if in small bin range)
- For large requests, call
to move fast chunks to unsortedmalloc_consolidate() - Search unsorted bin
- Search large bins (current index, then larger)
- Use top chunk or call
sysmalloc()
malloc_consolidate(arena)
malloc_consolidate(arena)Called for large allocations to prevent fragmentation.
What it does:
- Removes all chunks from fast bins
- Merges adjacent free chunks (prev/next if not in use)
- Places consolidated chunks in unsorted bin
- Sets
have_fastchunks = false
Security checks performed:
- chunk misalignedunaligned fastbin chunk detected
- size doesn't match fastbin indexinvalid chunk size
- prev_size mismatchcorrupted size vs. prev_size in fastbins
sysmalloc(bytes, arena)
sysmalloc(bytes, arena)Requests memory from the system when bins are exhausted.
When called:
- No arena exists (first allocation)
- Top chunk too small and no fast chunks to consolidate
- Request size exceeds mmap threshold with mmap available
Strategies:
- Try
for large allocations or when arena is nullsysmalloc_mmap() - For non-main arena: extend heap or allocate new heap
- For main arena: call
(sbrk) to extend heapMORECORE - Fallback to mmap if sbrk fails
Bin Types and Characteristics
Tcache
Purpose: Thread-local cache for fast allocations
Behavior:
- Checked first in
__libc_malloc() - Filled from fast bins and small bins during allocation
- Has per-size counts and unsorted limit
- Chunks are singly-linked (fd pointer only)
Key points:
chunks per bin maximumtcache_count
limits unsorted bin processingtcache_unsorted_limit- Filled proactively when other bins are checked
Fast Bins
Purpose: Very fast allocation for small chunks
Characteristics:
- Size range: up to
(typically 80 bytes)get_max_fast() - Singly-linked list (fd pointer)
- No size verification on removal (security risk)
- One chunk per size index
Security checks:
- misaligned chunkunaligned fastbin chunk detected
- misaligned victimunaligned fastbin chunk detected 2
- misaligned tcache fill chunkunaligned fastbin chunk detected 3
- size doesn't match indexmemory corruption (fast)
Tcache interaction: When a fast bin chunk is used, remaining chunks of same size are moved to tcache
Small Bins
Purpose: Fast allocation for small chunks with integrity checks
Characteristics:
- Size range:
toMINSIZE
(typically 80-512 bytes)MAX_SMALLBIN - Doubly-linked list (fd/bk pointers)
- One exact size per index
- Security check:
bck->fd == victim
Security checks:
- integrity check failedsmallbin double linked list corrupted
Tcache interaction: Remaining chunks moved to tcache after allocation
Unsorted Bin
Purpose: Temporary holding for freed chunks before binning
Characteristics:
- First-fit search (uses first chunk that fits)
- Chunks are binned here before being sorted to small/large bins
- Maintains
for small allocation localitylast_remainder
Security checks (per chunk):
- size too small or too biginvalid size (unsorted)
- next chunk size invalidinvalid next size (unsorted)
- prev_size mismatchmismatching next->prev_size (unsorted)
- fd/bk integrityunsorted double linked list corrupted
- prev_inuse bit wronginvalid next->prev_inuse (unsorted)
Special behavior:
- If exact fit found and tcache not full, add to tcache instead of returning
used for small allocations to promote localitylast_remainder
(10000) limit on traversalMAX_ITERS
Large Bins
Purpose: Store larger chunks with best-fit search
Characteristics:
- Size range: above small bin maximum
- Doubly-linked with skip list (fd_nextsize/bk_nextsize)
- Sorted by size within bin
- Bitmap (
) tracks non-empty binsbinmap
Security checks:
- skip list integritylargebin double linked list corrupted (nextsize)
- main list integritylargebin double linked list corrupted (bk)
Search strategy:
- Check current bin index for smallest fitting chunk
- If not found, scan larger bins using bitmap
- Split chunk if remainder >= MINSIZE
Top Chunk
Purpose: Last chunk in arena, can be extended
Characteristics:
- Points to end of available memory
- Can be split for allocations
- Extended via
when too smallsysmalloc()
Security check:
- size exceedscorrupted top sizesystem_mem
Behavior:
- If large enough, split and return portion
- If not enough and fast chunks exist, consolidate and retry
- Otherwise call
sysmalloc()
Security Checks Summary
| Check | Location | Error Message |
|---|---|---|
| Fastbin alignment | _int_malloc | |
| Fastbin size | _int_malloc | |
| Smallbin integrity | _int_malloc | |
| Unsorted size | _int_malloc | |
| Unsorted next size | _int_malloc | |
| Unsorted prev_size | _int_malloc | |
| Unsorted integrity | _int_malloc | |
| Unsorted prev_inuse | _int_malloc | |
| Largebin nextsize | _int_malloc | |
| Largebin bk | _int_malloc | |
| Top size | _int_malloc | |
| Unsorted chunks | _int_malloc | |
| Consolidate alignment | malloc_consolidate | |
| Consolidate size | malloc_consolidate | |
| Consolidate prev_size | malloc_consolidate | |
Common Heap Exploitation Concepts
Fastbin Attack
Vulnerability: Fast bins don't verify chunk size on removal
Exploitation:
- Free chunks to populate fast bin
- Corrupt chunk size to be larger than index
- Allocate to get larger chunk than expected
- Overwrite adjacent chunk's fd pointer
Mitigation: Tcache, fastbin size checks (glibc 2.31+)
Unsorted Bin Attack
Vulnerability: Unsorted bin uses first-fit, chunks binned after use
Exploitation:
- Allocate chunk A, free it (goes to unsorted)
- Allocate chunk B (takes A from unsorted, bins A's remainder)
- Free chunk C (goes to unsorted)
- Allocate chunk D (takes C, bins C's remainder)
- If A's remainder was smaller than C, A's remainder is now in wrong bin
Mitigation: Understanding binning behavior
Tcache Poisoning
Vulnerability: Tcache is thread-local, no size verification
Exploitation:
- Fill tcache with controlled chunks
- Corrupt fd pointers in tcache
- Allocate to get arbitrary pointer
Mitigation: Tcache per-thread, fd pointer checks
Arena and Multi-threading
Main Arena:
- First arena created
- Uses sbrk for memory
- Shared by all threads initially
Thread Arenas:
- Created when thread allocates
- Uses mmap for memory
- Reduces lock contention
Arena Selection:
- Single-threaded: always main arena
- Multi-threaded:
finds suitable arenaarena_get() - May retry with different arena if allocation fails
Memory Alignment
Key constants:
- typically 16 bytesMALLOC_ALIGNMENT
- chunk header size (typically 16 bytes)CHUNK_HDR_SZ
- minimum allocatable sizeMINSIZE
- system page size (typically 4096 bytes)pagesize
Alignment rules:
- All returned pointers are MALLOC_ALIGNMENT aligned
- Chunks are aligned to page boundaries when allocated from system
handles alignment in mmap'd regionsfront_misalign
Practical Usage
When to use this skill:
- Understanding malloc behavior: "Why did this allocation come from tcache?"
- Heap exploitation: "How can I exploit a use-after-free in fastbins?"
- CTF challenges: "This heap challenge requires understanding unsorted bin attacks"
- Debugging: "Why is malloc returning chunks in this order?"
- Security research: "What security checks prevent this heap corruption?"
- Learning: "Explain how glibc malloc works"
How to approach heap problems:
- Identify the allocation path: What size? What bins are involved?
- Track chunk state: What's in each bin? What's the top chunk?
- Understand the vulnerability: Which security check can be bypassed?
- Plan the exploitation: What allocations/frees achieve the goal?
- Consider mitigations: Tcache, ASLR, stack canaries, etc.
Key questions to ask:
- What size is being allocated?
- Which bin will it come from?
- What security checks apply?
- What's the current heap state?
- Can we control the fd/bk pointers?
- Is tcache enabled?
- Are we in main arena or thread arena?
References
- glibc malloc source: https://github.com/bminor/glibc/blob/master/malloc/malloc.c
- malloc(3) man page
- Various heap exploitation writeups and tutorials
Note: This skill covers glibc's ptmalloc2 implementation. Behavior may vary slightly between glibc versions. Always verify against the specific version you're working with.