Overview
The first-fit algorithm is the core allocation strategy used by glibc malloc when selecting a free chunk to satisfy a memory request. When malloc needs to allocate memory, it searches through the appropriate bin and returns the first chunk that is large enough, rather than searching for the best-fitting chunk.This seemingly simple design decision has significant implications for heap exploitation, particularly in use-after-free scenarios.
How First-Fit Works
When you callmalloc(size), the allocator:
1
Calculates required size
Converts the requested size to the actual chunk size needed (including metadata and alignment).
2
Searches for a free chunk
Looks through the appropriate bin (tcache, fastbin, smallbin, etc.) for a free chunk.
3
Returns first match
Returns the first chunk that is large enough, even if a better-fitting chunk exists later in the list.
4
Splits if necessary
If the chunk is significantly larger than needed, it may be split, with the remainder returned to the free list.
First-fit prioritizes speed over optimal memory usage. It avoids traversing the entire free list to find the best match.
Demonstration Program
The following program demonstrates first-fit allocation behavior:first_fit.c
Running the Program
Key Observations
Let’s break down what happens in this program:1
Initial allocations
a contains “this is A!”.2
Free first chunk
3
Allocate smaller chunk
a’s address is large enough. First-fit returns this chunk immediately.4
Use-after-free
a and c point to the same memory. Reading from a shows data written via c.Exploitation Implications
First-fit allocation makes certain heap exploits more reliable:Use-After-Free (UAF)
Example UAF scenario
Heap Spray
First-fit makes heap spraying more predictable:1
Allocate many objects
Fill the heap with objects containing exploit payloads.
2
Trigger vulnerability
Cause a UAF or similar bug that allocates memory.
3
Exploit
Because of first-fit, the vulnerability is likely to reuse one of your controlled chunks.
Heap Feng Shui
Exploiters can manipulate heap layout by:- Allocating chunks in specific order
- Freeing strategic chunks to create controlled free list
- Triggering vulnerability that allocates from manipulated free list
- Achieving predictable memory reuse due to first-fit
Why Not Best-Fit?
You might wonder why glibc doesn’t use a best-fit algorithm (find the smallest chunk that fits). The answer is performance:First-Fit
- Fast: O(1) to O(n) with early exit
- Returns first match found
- Less memory traversal
- Good locality
Best-Fit
- Slow: O(n) always
- Must check all chunks
- More memory traversal
- Better memory efficiency
For most applications, the performance gain from first-fit outweighs the slight memory fragmentation cost.
Defense Considerations
To protect against first-fit-based exploits:1
Avoid use-after-free
Null out pointers after freeing them, and implement proper lifetime management.
2
Use memory safety tools
AddressSanitizer can detect UAF bugs during development.
3
Consider safe languages
Languages with automatic memory management eliminate entire classes of heap exploits.
4
Enable hardening features
Use allocators with additional security checks (e.g., safe linking in modern glibc).
Practical Exercise
Try this experiment with the program:1
Modify the allocation size
Change
malloc(0x500) to malloc(0x520) (larger than the freed chunk).2
Observe the result
The new allocation will get a different address because it doesn’t fit.
3
Try with tcache
Allocate/free 7 same-sized chunks to fill tcache, then observe first-fit behavior.
Related Techniques
Tcache Poisoning
Exploit tcache’s LIFO structure with first-fit
Fastbin Dup
Double-free with first-fit allocation
House of Spirit
Create fake chunks that first-fit will allocate
Heap Basics
Review malloc fundamentals
Summary
First-fit allocation is:
- Fast: Returns the first suitable chunk without exhaustive search
- Predictable: Same allocation patterns produce consistent results
- Exploitable: Enables reliable use-after-free and heap grooming attacks
- Fundamental: Understanding this is essential for heap exploitation
