Skip to content

fix(memory): PoolAllocator double-free silently corrupts free list — no detection #697

Description

@JeanPhilippeKernel

Problem

PoolAllocator::Free asserts that the pointer is in-range and chunk-aligned, but does NOT detect double-free. A second call to Free with the same pointer passes both assertions (pointer is still valid by both checks) and corrupts the free list by inserting a cycle.

Consequence

The next Allocate() call after a double-free returns a pointer that is simultaneously live in two places. Writes through either alias corrupt the other. In Release builds this is a silent memory corruption with no crash until much later.

Fix

Add a per-chunk IsAllocated bitset or, simpler, validate that the pointer's PoolFreeNode::Next field looks like a valid free-list node before inserting (a heuristic, not a guarantee). For Debug builds only, a per-chunk uint8_t Allocated flag is acceptable overhead.

Reproducer

PoolAllocator pool;
pool.Initialize(&arena, 1024, 128);
void* p = pool.Allocate();
pool.Free(p);
pool.Free(p);           // silent corruption — no assert fires
void* q = pool.Allocate();
void* r = pool.Allocate(); // q == r — both aliases of the same chunk

References

memory-architecture.md — PoolAllocator Safety Invariants section (double-free note)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P2High priority — next sprintbugSomething isn't working

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions