A pointer is dangling when it references freed memory. Typical examples can be found here.
指针在引用释放的内存时呈悬空状态。典型例子可以在这里找到。
Dangling pointers are not a problem unless they are subsequently dereferenced and/or used for other purposes. Proving that pointers are unused has turned out to be difficult in general, especially in face of future modifications to the code. Hence, they are a source of UaF bugs and highly discouraged unless you are able to ensure that they can never be used after the pointed-to objects are freed.
悬空指针不是问题,除非它们随后被取消引用和/或用于其他目的。事实证明,证明指针未被使用通常是困难的,尤其是在面对未来对代码的修改时。因此,它们是 UaF 错误的来源,除非您能够确保在释放指向对象后永远无法使用它们,否则强烈建议不要使用它们。
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:
在构建标志后面,Chrome 实现了一个悬空指针检测器。每当raw_ptr晃动时,它会导致 Chrome 崩溃:
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.
另一方面,我们不能简单地禁止所有悬空指针的使用,因为存在有效的用例。该 DisableDanglingPtrDetection
选项可用于批注“有意且安全”的悬空指针。它应该被用作最后的手段,只有在没有更好的方法来重新构建代码时。
raw_ptr<T, DisableDanglingPtrDetection> ptr_may_dangle;
The DanglingUntriaged
option has been used to annotate pre-existing dangling pointers in Chrome:
该 DanglingUntriaged
选项已用于对 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.
与 DisableDanglingPtrDetection
此相反,我们还不知道它为什么会晃来晃去。它要么被重构以避免悬空,要么变成“DisableDanglingPtrDetection”,并带有解释会发生什么的注释。
How to check for dangling pointers?
如何检查悬空指针?
On Linux, it is enabled by default on most configurations. To be precise: (is_debug
or dcheck_always_on
) and non is_official
builds.
在 Linux 上,默认情况下,它在大多数配置中处于启用状态。准确地说:( is_debug
或 dcheck_always_on
) 和 non is_official
builds。
For the other operating systems, this is gated by both build and runtime flags:
对于其他操作系统,这由生成和运行时标志控制:
Build flags 生成标志
gn args ./out/dangling/
use_goma = true is_debug = false # Important! (*) is_component_build = false # Important! (*) dcheck_always_on = true enable_backup_ref_ptr_support = true # true by default on some platforms enable_dangling_raw_ptr_checks = true
(*) We want to emphasize that setting either is_debug = false
or is_component_build = false
is important. It is a common mistake to set is_debug
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
.
(*)我们想强调的是,设置要么很重要,要么 is_debug = false
is_component_build = false
很重要。设置为 is_debug
true
是一个常见的错误,这反过来又会打开组件构建,从而禁用 PartitionAlloc-Everywhere。 enable_backup_ref_ptr_support = true
不能在没有 PartitionAlloc-Everywhere 的情况下使用,并且以静默方式设置为 false
。
Runtime flags 运行时标志
./out/dangling/content_shell \ --enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr
By default, Chrome will crash on the first dangling raw_ptr detected.
默认情况下,Chrome 会在检测到第一个悬空raw_ptr时崩溃。
Runtime flags options: 运行时标志选项:
Mode parameter 模式参数
Crash (default) 崩溃(默认)
--enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:mode/crash
Record a list of signatures
记录签名列表
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 "[DanglingSignature]" \ | cut -f2,3,4,5 \ | sort \ | uniq -c \ | sed -E 's/^ *//; s/ /\t/' \ | sort -rn
This is used to list issues and track progresses.
这用于列出问题并跟踪进度。
Type parameter 类型参数
Select all dangling raw_ptr (default)
选择所有悬空raw_ptr(默认)
The option: type/all
selects every dangling pointer.
选项: type/all
选择每个悬空指针。
Example usage: 用法示例:
./out/dangling/content_shell \ --enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:type/all
Select cross tasks dangling raw_ptr
选择悬空的交叉任务raw_ptr
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.
选项: type/cross_task
选择在与释放内存的任务不同的任务中释放的悬空指针。这些更有可能导致 UAF。
Example usage: 用法示例:
./out/dangling/content_shell \ --enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:type/cross_task
Combination 组合
Both parameters can be combined, example usage:
两个参数可以组合使用,示例用法:
./out/dangling/content_shell \ --enable-features=PartitionAllocBackupRefPtr,PartitionAllocDanglingPtr:mode/log_only/type/cross_task \ |& tee output
Alternative dangling pointer detector (experimental)
替代悬垂指针检测器(实验性)
The dangling pointer detector above works only against certain heap allocated objects, but there is an alternate form that catches other cases such as pointers to out-of-scope stack variables or pointers to deallocated shared memory regions. The GN arguments to enable it are:
上面的悬空指针检测器仅对某些堆分配的对象起作用,但还有一种替代形式可以捕获其他情况,例如指向超出范围的堆栈变量的指针或指向已释放的共享内存区域的指针。启用它的 GN 参数是:
enable_backup_ref_ptr_support=false is_asan=true is_component_build=false use_asan_backup_ref_ptr=false use_asan_unowned_ptr=true
This will crash when the object containing the dangling ptr is destructed, giving the usual three-stack trace from ASAN showing where the deleted object was allocated and freed.
当包含悬空 ptr 的对象被破坏时,这将崩溃,从而给出 ASAN 中通常的三堆栈跟踪,显示已删除对象的分配和释放位置。
When running under this mode, there is no need to specify any –enable-features flag as above.
在此模式下运行时,无需指定任何 –enable-features 标志,如上所述。
原文始发于chromium:Dangling Pointer Detector