Overview
Fastbin Dup Consolidate is an elegant technique that leveragesmalloc_consolidate() to bypass the typical double-free restrictions. By triggering consolidation of fastbins with the top chunk, we can create two pointers to the same memory region - one from the original allocation and one after it’s been merged and reallocated. This works even with large, tcache-sized chunks.
Glibc Version Compatibility: Latest (tested on glibc 2.23 - 2.41)This technique exploits a fundamental behavior of malloc_consolidate that exists across all versions.
What This Achieves
- Chunk duplication: Two pointers to the same memory without direct double-free
- Large chunk control: Works with tcache-sized chunks (up to 0x410) and larger
- Bypass PREV_INUSE check: Large chunks normally resist double-free due to PREV_INUSE validation
- Heap feng shui: Precise control over chunk placement
Prerequisites
- Ability to trigger large allocation (>= 0x3f0 bytes requested)
- Control over free operations
- Ability to free the same chunk twice (double-free vulnerability)
- Understanding of tcache fill behavior
Understanding malloc_consolidate
malloc_consolidate() is a critical internal function that merges all fastbin chunks with their neighbors, places them in the unsorted bin, and merges them with the top chunk if possible.When is it called?- Large allocation: Requesting chunk size >= 0x400 (smallbin threshold)
- Top too small: No suitable bins and top chunk insufficient
- Large free: Freeing chunk >= 65536 bytes (FASTBIN_CONSOLIDATION_THRESHOLD)
- Manual triggers:
malloc_trim()ormallopt()
The Technique
Step-by-Step Walkthrough
Fill the tcache
Allocate and free 7 chunks to fill the tcache for our target size (0x40).Now the tcache is full, so freeing p1 will go to fastbin.
Trigger malloc_consolidate
Request a large allocation (>= 0x400). This triggers What happens:
malloc_consolidate().- malloc_consolidate merges p1 with the top chunk
- p2 is allocated from the new top
- Result:
p1 == p2(same address!)
Double-free the duplicated chunk
Now we have two pointers (p1 and p2) to the same memory. Free through p1 again.This places the 0x410 chunk in the tcache. p2 still points to it but hasn’t been freed directly.
Full Source Code
Key Concepts
Why does malloc_consolidate help?
Why does malloc_consolidate help?
Normally, double-freeing a large chunk triggers a PREV_INUSE check that crashes the program. However:
- We free a small fastbin chunk (p1)
- malloc_consolidate merges it with top
- We allocate a large chunk (p2) from the new top
- p1 and p2 now point to the same address
- We free p1 again - but this time it’s treated as a 0x410 chunk (the size at p2)
- No double-free detection because p2 was never freed directly
Why target 0x400 request size?
Why target 0x400 request size?
The magic number 0x400 (requesting 0x3f0-0x3ff bytes) is significant:
- Actual chunk size allocated: 0x410 (includes metadata)
- This is the largest tcache-sized chunk
- Triggers malloc_consolidate (>= large bin threshold)
- Allows duplication of a tcache-manageable chunk
malloc_consolidate internals
malloc_consolidate internals
When malloc_consolidate is triggered:In our case, p1 is adjacent to top, so it gets merged with top. When we allocate p2, it comes from this expanded top, landing at the same address as p1.
Common Use Cases
- Overlapping chunks: Create multiple valid pointers to the same large chunk
- Bypass large bin protections: Circumvent PREV_INUSE checks on large chunks
- Tcache manipulation: Control tcache behavior with large allocations
- Heap grooming: Precisely control heap layout through consolidation
Variations
Using larger chunks (> 0x410)
Using larger chunks (> 0x410)
The technique works with any large size:Difference: with sizes > 0x410, chunks come from unsorted bin instead of tcache.
Multiple fastbin chunks
Multiple fastbin chunks
You can consolidate multiple fastbin chunks simultaneously:This can create complex heap layouts.
Defense Mechanisms
Why this still works:
- malloc_consolidate is a fundamental performance optimization
- No practical way to prevent the merging behavior
- The double-free happens across different “contexts” (small vs large chunk)
- Allocator state tracking doesn’t span consolidation events
CTF Challenges
Hitcon CTF 2016
SleepyHolder - Classic challenge using fastbin consolidationWriteup
Related Techniques
- Fastbin Dup - Basic double-free primitive
- [House of Einherjar/techniques/house/house-of-einherjar) - Another consolidation-based technique
- [Poison Null Byte/techniques/advanced/poison-null-byte) - Chunk consolidation through metadata corruption
Practice & Resources
Ret2 Wargames
Debug this technique interactively in your browser using GDB
