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:

  1. Construction and Assignment: Whenever a RawPtr is created to point to an object inside PartitionAlloc's memory space, or when a RawPtr is copied, it locates the metadata for that specific memory slot and increments the reference count by one.
  2. Destruction and Reassignment: When a RawPtr goes out of scope, is destroyed, or is reassigned to point to a different address (or nullptr), 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 RawPtr attempts 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.

  1. 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.
  2. The application continues to run until the dangling RawPtr is finally destroyed or reset.
  3. When that RawPtr decrements the reference count, it checks the metadata and sees that the "freed" bit was already set.
  4. 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.