blob: c48ec1982570dfb09a7399cfe5c2b60236a715c6 [file] [log] [blame] [view]
Arthur Sonzognie17a10f2024-01-19 12:57:24 +00001# Dangling Pointer Detector
2
3A pointer is dangling when it references freed memory. Typical examples can be found
4[here](https://docs.google.com/document/d/11YYsyPF9rQv_QFf982Khie3YuNPXV0NdhzJPojpZfco/edit?resourcekey=0-h1dr1uDzZGU7YWHth5TRAQ#heading=h.wxt96wl0k0sq).
5
6Dangling pointers are not a problem unless they are subsequently dereferenced and/or used for other
7purposes. Proving that dangling pointers are unused has turned out to be difficult in general,
8especially in face of future modifications to the code. Hence, they are a source of UaF bugs and
9highly discouraged unless you are able to ensure that they can never be used after the pointed-to
10objects are freed.
11
12Dawn tests are configured to detect dangling pointers.
13
14## Level of support
15
16The dangling pointer detector is an optional dependency of Dawn. It is enabled only when running
17tests in the dawn_standalone configuration. It is also enforced as part of Chrome's tests.
18
19It is currently enforced under this configuration:
20
21| System | Compiler | Build system | Directory | Final embedder | Misc |
22| ----------- | -------- | ------------ | ----------- | -------------------- | ---------------------------- |
23| ✅ Android | ✅ Clang | ✅ GN | ✅ src/dawn | ✅ Dawn (standalone) | ❌ windows + debug |
24| ✅ Windows | ✅ GCC | ❌ CMake | ❌ src/tint | ❌ Skia | ❌ windows + component_build |
25| ✅ Mac | ❌ MSVC | ❌ Bazel | | ✅ Chrome | ❌ sanitizers |
26| ✅ Linux | ❌ _ | ❌ _ | | ❌ _ | ✅ _ |
27| ✅ ChromeOS | | | | | |
28| ✅ Fuchsia | | | | | |
29| ❌ iOS | | | | | |
30| ❌ _ | | | | | |
31
32## raw_ptr<>
33
34A `raw_ptr<T>` is a non-owning pointer. When using this kind of pointer, the severity of UAFs can be
35reduced, because they are protected by
36[MiraclePtr/BackupRefPtr](https://security.googleblog.com/2022/09/use-after-freedom-miracleptr.html)
37
38A `raw_ptr<T>` is transparently usable as a `T*`. It should be used in class and struct member
39variable.
40
41In general, it shouldn't be used elsewhere: local variable, function arguments, etc...
42
43## raw_ptr flavors
44
45`raw_ptr<T>` comes in 3 main flavors:
46```cpp
47raw_ptr<T> ptr_never_dangling;
48raw_ptr<T, DisableDanglingPtrDetection> ptr_allowed_to_dangle;
49raw_ptr<T, DanglingUntriaged> ptr_dangling_to_investigate;
50```
51
52The `DisableDanglingPtrDetection` option can be used to annotate intentional-and-safe dangling
53pointers. It is meant to be used as a last resort, only if there is no better way to re-architecture
54the code.
55
56The `DanglingUntriaged` means the pointer was dangling at the time of the
57initial rewrite. We should investigate why. No new occurences should be added.
58
59## Pointer arithmetic
60
61The use of pointer arithmetic with `raw_ptr<T>` is discouraged and disabled by default. Usually a
62container like `std::span<>` should be used instead of the `raw_ptr`.
63
64The `AllowPtrArithmetic` option can be used to enable pointer arithmetic. For instance:
65```
66raw_ptr<T, AllowPtrArithmetic> artihmetic_ptr.
67```
68
69## Chrome's documentation
70
71The dangling pointer detector is part of Chrome too. You can use the main
72documentation:
73- [Dangling pointers detector](https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md)
74- [Fixing dangling pointers guide](https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr_guide.md)
75
76## Dawn's specificities.
77
78Contrary to chrome, Dawn is not yet configured to display useful StackTraces and TaskTraces. It displays the error:
79```
80DanglingPointerDetector: A pointer was dangling!
81 Documentation: https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/docs/dangling-pointer-detector.md
82```
83
84To debug you can:
85- **remotely**: Find a failing bot on the CQ running tests inside Chrome. You
86 will find useful debugging informations.
87- **locally**: Use a debugger to display the StackTrace. Dawn is configured to crash when the
88 dangling raw_ptr is released. If needed, you can also understand where the memory was freed by
89 replacing `SetDanglingRawPtrReleasedFn` by `SetDanglingRawPtrDetectedFn` in
90 src/dawn/tests/PartitionAllocSupport.cpp`.
91
92## Other resources
93- [MiraclePtr in Dawn design doc](https://docs.google.com/document/d/1wz45t0alQthsIU9P7_rQcfQyqnrBMXzrOjSzdQo-V-A/edit#heading=h.vn4i6wy373x7)
94- [MiraclePtr in chrome](https://chromium.googlesource.com/chromium/src/+/ddc017f9569973a731a574be4199d8400616f5a5/base/memory/raw_ptr.md)
95- [Use-after-freedom: MiraclePtr](https://security.googleblog.com/2022/09/use-after-freedom-miracleptr.html)
96- [MiraclePtr: protecting users from use-after-free vulnerabilities on more platforms](https://security.googleblog.com/2024/01/miracleptr-protecting-users-from-use.html)