Dangling pointers are not a problem unless they are dereferenced and used. However, they are a source of UaF bugs and highly discouraged unless you are 100% confident that they are never dereferenced after the pointed-to objects are freed.
See also the Dangling Pointers Guide for how to fix cases where dangling pointers occur.
Behind build flags, Chrome implements a dangling pointer detector. It causes Chrome to crash, whenever a raw_ptr becomes dangling:
raw_ptr<T> ptr_never_dangling;
On the other hand, we cannot simply ban all the usage of dangling pointers
because there are valid use cases. The DisableDanglingPtrDetection
option can
be used to annotate "intentional-and-safe" dangling pointers. It is meant to be
used as a last resort, only if there is no better way to re-architecture the
code.
raw_ptr<T, DisableDanglingPtrDetection> ptr_may_dangle;
The DanglingUntriaged
option has been used to annotate pre-existing dangling
pointers in Chrome:
raw_ptr<T, DanglingUntriaged> ptr_dangling_mysteriously;
Contrary to DisableDanglingPtrDetection
, we don't know yet why it dangles. It
is meant to be either refactored to avoid dangling, or turned into
"DisableDanglingPtrDetection" with a comment explaining what happens.
It is gated behind both build and runtime flags:
gn args ./out/dangling/
use_goma = true
is_debug = false # Important! (*)
dcheck_always_on = true
enable_backup_ref_ptr_support = true # true by default on most platforms
enable_dangling_raw_ptr_checks = true
(*) We want to emphasize that is_debug = false
is important. It is a common
mistake to set it to true
, which in turn turns on component builds, which
disables PartitionAlloc-Everywhere. enable_backup_ref_ptr_support = true
can't
be used without PartitionAlloc-Everywhere, and is silently set to false
.
./out/dangling/content_shell \
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr
By default, Chrome will crash on the first dangling raw_ptr detected.
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:mode/crash
Example usage:
./out/dangling/content_shell \
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:mode/log_only \
|& tee output
The logs can be filtered and transformed into a tab separated table:
cat output \
| grep "[DanglingRawPtrSignature]" \
| cut -f2,3,4,5 \
| sort \
| uniq -c \
| sed -E 's/^ *//; s/ /\t/' \
| sort -rn
This is used to list issues and track progresses.
The option: type/all
selects every dangling pointer.
Example usage:
./out/dangling/content_shell \
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:type/all
The option: type/cross_task
selects dangling pointers that are released in a
different task than the one where the memory was freed. Those are more likely to
cause UAF.
Example usage:
./out/dangling/content_shell \
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:type/cross_task
Both parameters can be combined, example usage:
./out/dangling/content_shell \
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:mode/log_only/type/cross_task \
|& tee output