How RawPtr Tracks References to Detect Dangling Pointers
This article explains how the Chromium web browser uses the
RawPtr wrapper within its PartitionAlloc-Everywhere memory
allocator to track reference counts and detect dangling pointers. By
replacing standard C++ pointers with RawPtr (commonly
implemented as raw_ptr or BackupRefPtr), Chromium embeds
hidden reference counts into memory allocations. This mechanism allows
the allocator to identify when freed memory is still being referenced,
quarantine compromised memory blocks, and actively alert developers to
Use-After-Free (UAF) bugs.
PartitionAlloc-Everywhere and the RawPtr Wrapper
PartitionAlloc-Everywhere is Chromium's unified memory allocator,
designed to handle all heap allocations across the browser for maximum
performance and security. Because C++ does not natively prevent dangling
pointers—pointers that still reference a memory address after the
underlying object has been destroyed—Chromium introduced the
RawPtr wrapper.
RawPtr acts as a drop-in replacement for standard C++
raw pointers (T*). Unlike std::shared_ptr,
which keeps an object alive until the last reference is gone,
RawPtr does not manage the lifecycle of the object itself.
Instead, it communicates with PartitionAlloc to track how many pointers
are currently looking at a specific chunk of memory.
How Reference Counting Works in Memory
PartitionAlloc organizes memory into structured regions called "super
pages," which are further divided into "slot spans" that hold individual
memory allocations. To support RawPtr, PartitionAlloc
allocates a small amount of hidden metadata—specifically, a reference
count—associated with every allocation slot.
The tracking process follows strict rules during the lifecycle of a
RawPtr:
- Construction and Assignment: Whenever a
RawPtris created to point to an object inside PartitionAlloc's memory space, or when aRawPtris copied, it locates the metadata for that specific memory slot and increments the reference count by one. - Destruction and Reassignment: When a
RawPtrgoes out of scope, is destroyed, or is reassigned to point to a different address (ornullptr), it decrements the reference count for the original memory slot by one.
Because PartitionAlloc controls the exact layout of the heap,
RawPtr can calculate the location of the reference count
using fast bitwise operations on the memory address itself, avoiding the
need for slow hash table lookups.
Intercepting the Free Operation
The core of dangling pointer detection happens when the application
attempts to delete an object. When free() or
delete is called on a memory address, PartitionAlloc
intercepts the request and checks the hidden reference count for that
allocation slot before returning the memory to the system.
Scenario 1: Reference Count is Zero
If the reference count is zero, no RawPtr instances are
pointing to the object. PartitionAlloc safely marks the memory slot as
free, allowing it to be reused immediately for future allocations.
Scenario 2: Reference Count is Greater Than Zero
If the reference count is one or more, it means the object is being
destroyed while at least one RawPtr still points to it.
That RawPtr has now officially become a dangling
pointer.
Memory Quarantine and Poisoning
In production builds of Chromium, detecting a reference count greater than zero during deallocation triggers a defensive mitigation process:
- Memory Poisoning: PartitionAlloc immediately
overwrites the freed memory slot with a specific pattern of "poison"
bytes. If the dangling
RawPtrattempts to dereference and use this memory later, the application will likely crash safely rather than allowing an attacker to execute arbitrary code. - Quarantine: PartitionAlloc places the memory slot into a quarantine state. It refuses to reallocate this memory address to any new objects.
The memory remains in quarantine until the remaining
RawPtr instances are eventually destroyed or reassigned.
Once the last RawPtr decrements the reference count to
zero, PartitionAlloc removes the memory slot from quarantine and makes
it available for reuse.
Active Detection with the Dangling Pointer Detector
While quarantining prevents security exploits in production, Chromium
also uses RawPtr reference counts to actively eradicate
bugs during development via the Dangling Pointer Detector (DPD).
In testing builds, PartitionAlloc reserves a specific bit in the reference count metadata to track whether the underlying object has been freed.
- When an object is freed while its reference count is still greater
than zero, PartitionAlloc does not immediately crash. Instead, it sets
the "freed" bit in the metadata and records the stack trace of the
free()operation. - The application continues to run until the dangling
RawPtris finally destroyed or reset. - When that
RawPtrdecrements the reference count, it checks the metadata and sees that the "freed" bit was already set. - This triggers an immediate diagnostic crash, providing the developer with two vital pieces of information: the stack trace of where the memory was prematurely freed, and the stack trace of where the dangling pointer was finally released.