xref: /aosp_15_r20/external/cronet/base/memory/raw_ptr.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# raw_ptr<T> (aka. MiraclePtr, aka. BackupRefPtr, aka. BRP)
2*6777b538SAndroid Build Coastguard Worker
3*6777b538SAndroid Build Coastguard Worker## Quick rules
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard WorkerBefore telling you what `raw_ptr<T>` is, we'd like you to follow one simple
6*6777b538SAndroid Build Coastguard Workerrule: think of it as a raw C++ pointer. In particular:
7*6777b538SAndroid Build Coastguard Worker- Initialize it yourself, don't assume the constructor default-initializes it
8*6777b538SAndroid Build Coastguard Worker  (it may or may not). (Always use the `raw_ptr<T> member_ = nullptr;` form of
9*6777b538SAndroid Build Coastguard Worker  initialization rather than the so-called uniform initialization form
10*6777b538SAndroid Build Coastguard Worker  (empty braces) `raw_ptr<T> member_{};` whose meaning varies with the
11*6777b538SAndroid Build Coastguard Worker  implementation.)
12*6777b538SAndroid Build Coastguard Worker- Don't assume that moving clears the pointer (it may or may not).
13*6777b538SAndroid Build Coastguard Worker- The owner of the memory must free it when the time is right, don't assume
14*6777b538SAndroid Build Coastguard Worker  `raw_ptr<T>` will free it for  you (it won't). Unlike `std::unique_ptr<T>`,
15*6777b538SAndroid Build Coastguard Worker  `base::scoped_refptr<T>`, etc., it does not manage ownership or lifetime of
16*6777b538SAndroid Build Coastguard Worker  an allocated object.
17*6777b538SAndroid Build Coastguard Worker  - if the pointer is the owner of the memory, consider using an alternative
18*6777b538SAndroid Build Coastguard Worker    smart pointer.
19*6777b538SAndroid Build Coastguard Worker- Don't assume `raw_ptr<T>` will protect you from freeing memory too early (it
20*6777b538SAndroid Build Coastguard Worker  likely will, but there are gotchas; one of them is that dereferencing will
21*6777b538SAndroid Build Coastguard Worker  result in other type of undefined behavior).
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker(There are other, much more subtle rules that you should follow, but they're
24*6777b538SAndroid Build Coastguard Workerharder to accidentally violate, hence discussed in the further section
25*6777b538SAndroid Build Coastguard Worker["Extra pointer rules"](#Extra-pointer-rules).)
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker## What is |raw_ptr&lt;T&gt;|
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` is a part of
30*6777b538SAndroid Build Coastguard Worker[the MiraclePtr project](https://docs.google.com/document/d/1pnnOAIz_DMWDI4oIOFoMAqLnf_MZ2GsrJNb_dbQ3ZBg/edit?usp=sharing)
31*6777b538SAndroid Build Coastguard Workerand currently implements
32*6777b538SAndroid Build Coastguard Worker[the BackupRefPtr algorithm](https://docs.google.com/document/d/1m0c63vXXLyGtIGBi9v6YFANum7-IRC3-dmiYBCWqkMk/edit?usp=sharing).
33*6777b538SAndroid Build Coastguard WorkerIf needed, please reach out to
34*6777b538SAndroid Build Coastguard Worker[[email protected]](https://groups.google.com/a/chromium.org/g/memory-safety-dev)
35*6777b538SAndroid Build Coastguard Workeror (Google-internal)
36*6777b538SAndroid Build Coastguard Worker[[email protected]](https://groups.google.com/a/google.com/g/chrome-memory-safety)
37*6777b538SAndroid Build Coastguard Workerwith questions or concerns.
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` is a non-owning smart pointer that has improved memory-safety over
40*6777b538SAndroid Build Coastguard Workerraw pointers.  It behaves just like a raw pointer on platforms where
41*6777b538SAndroid Build Coastguard WorkerENABLE_BACKUP_REF_PTR_SUPPORT is off, and almost like one when it's on. The main
42*6777b538SAndroid Build Coastguard Workerdifference is that when ENABLE_BACKUP_REF_PTR_SUPPORT is enabled, `raw_ptr<T>`
43*6777b538SAndroid Build Coastguard Workeris beneficial for security, because it can prevent a significant percentage of
44*6777b538SAndroid Build Coastguard WorkerUse-after-Free (UaF) bugs from being exploitable. It achieves this by
45*6777b538SAndroid Build Coastguard Workerquarantining the freed memory as long as any dangling `raw_ptr<T>` pointing to
46*6777b538SAndroid Build Coastguard Workerit exists, and poisoning it (with
47*6777b538SAndroid Build Coastguard Worker[0xEF..EF](https://source.chromium.org/chromium/chromium/src/+/main:base/allocator/partition_allocator/src/partition_alloc/partition_alloc_constants.h;l=488;drc=b5a738b11528b81c4cc2d522bfac88716c8aac49)
48*6777b538SAndroid Build Coastguard Workerpattern).
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard WorkerNote that the sheer act of dereferencing a dangling pointer won't
51*6777b538SAndroid Build Coastguard Workercrash, but poisoning increases chances that a subsequent usage of read memory
52*6777b538SAndroid Build Coastguard Workerwill crash (particularly if the read poison is interpreted as a pointer and
53*6777b538SAndroid Build Coastguard Workerdereferenced thereafter), thus giving us a chance to investigate and fix.
54*6777b538SAndroid Build Coastguard WorkerHaving said that, we want to emphasize that dereferencing a dangling pointer
55*6777b538SAndroid Build Coastguard Workerremains an Undefined Behavior.
56*6777b538SAndroid Build Coastguard Worker
57*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` protection is enabled by default in all non-Renderer processes, on:
58*6777b538SAndroid Build Coastguard Worker- Android (incl. AndroidWebView & Android WebEngine)
59*6777b538SAndroid Build Coastguard Worker- Windows
60*6777b538SAndroid Build Coastguard Worker- ChromeOS (incl. Ash & Lacros)
61*6777b538SAndroid Build Coastguard Worker- macOS
62*6777b538SAndroid Build Coastguard Worker- Linux
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard WorkerIn particular, it isn't enabled by default on:
65*6777b538SAndroid Build Coastguard Worker- iOS
66*6777b538SAndroid Build Coastguard Worker- ChromeCast
67*6777b538SAndroid Build Coastguard Worker- Fuchsia
68*6777b538SAndroid Build Coastguard Worker- Aix
69*6777b538SAndroid Build Coastguard Worker- Zos
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker[TOC]
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker## When to use |raw_ptr&lt;T&gt;|
74*6777b538SAndroid Build Coastguard Worker
75*6777b538SAndroid Build Coastguard Worker[The Chromium C++ Style Guide](../../styleguide/c++/c++.md#non_owning-pointers-in-class-fields)
76*6777b538SAndroid Build Coastguard Workerasks to use `raw_ptr<T>` for class and struct fields in place of
77*6777b538SAndroid Build Coastguard Workera raw C++ pointer `T*` whenever possible, except in Renderer-only code.
78*6777b538SAndroid Build Coastguard WorkerThis guide offers more details.
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard WorkerThe usage guidelines are currently enforced via Chromium Clang Plugin. We allow
81*6777b538SAndroid Build Coastguard Workerexclusions via:
82*6777b538SAndroid Build Coastguard Worker- `RAW_PTR_EXCLUSION` C++ attribute to exclude individual fields.  Examples:
83*6777b538SAndroid Build Coastguard Worker    - Cases where `raw_ptr<T>` won't compile (e.g. cases covered in
84*6777b538SAndroid Build Coastguard Worker      [the "Unsupported cases leading to compile errors" section](#Unsupported-cases-leading-to-compile-errors)).
85*6777b538SAndroid Build Coastguard Worker      Make sure to also look at
86*6777b538SAndroid Build Coastguard Worker      [the "Recoverable compile-time problems" section](#Recoverable-compile-time-problems).
87*6777b538SAndroid Build Coastguard Worker    - Cases where the pointer always points outside of PartitionAlloc
88*6777b538SAndroid Build Coastguard Worker      (e.g.  literals, stack allocated memory, shared memory, mmap'ed memory,
89*6777b538SAndroid Build Coastguard Worker      V8/Oilpan/Java heaps, TLS, etc.).
90*6777b538SAndroid Build Coastguard Worker    - (Very rare) cases that cause perf regression.
91*6777b538SAndroid Build Coastguard Worker    - (Very rare) cases where `raw_ptr<T>` can lead to runtime errors.
92*6777b538SAndroid Build Coastguard Worker      Make sure to look at
93*6777b538SAndroid Build Coastguard Worker      [the "Extra pointer rules" section](#Extra-pointer-rules)
94*6777b538SAndroid Build Coastguard Worker      before resorting to this exclusion.
95*6777b538SAndroid Build Coastguard Worker- [RawPtrManualPathsToIgnore.h](../../tools/clang/plugins/RawPtrManualPathsToIgnore.h)
96*6777b538SAndroid Build Coastguard Worker  to exclude at a directory level (NOTE, use it as last resort, and be aware
97*6777b538SAndroid Build Coastguard Worker  it'll require a Clang plugin roll).  Examples:
98*6777b538SAndroid Build Coastguard Worker    - Renderer-only code (i.e. code in paths that contain `/renderer/` or
99*6777b538SAndroid Build Coastguard Worker      `third_party/blink/public/web/`)
100*6777b538SAndroid Build Coastguard Worker    - Code that cannot depend on `//base`
101*6777b538SAndroid Build Coastguard Worker    - Code in `//ppapi`
102*6777b538SAndroid Build Coastguard Worker- No explicit exclusions are needed for:
103*6777b538SAndroid Build Coastguard Worker    - `const char*`, `const wchar_t*`, etc.
104*6777b538SAndroid Build Coastguard Worker    - Function pointers
105*6777b538SAndroid Build Coastguard Worker    - ObjC pointers
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard Worker## Examples of using |raw_ptr&lt;T&gt;| instead of raw C++ pointers
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard WorkerConsider an example struct that uses raw C++ pointer fields:
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker```cpp
112*6777b538SAndroid Build Coastguard Workerstruct Example {
113*6777b538SAndroid Build Coastguard Worker  int* int_ptr;
114*6777b538SAndroid Build Coastguard Worker  void* void_ptr;
115*6777b538SAndroid Build Coastguard Worker  SomeClass* object_ptr;
116*6777b538SAndroid Build Coastguard Worker  const SomeClass* ptr_to_const;
117*6777b538SAndroid Build Coastguard Worker  SomeClass* const const_ptr;
118*6777b538SAndroid Build Coastguard Worker};
119*6777b538SAndroid Build Coastguard Worker```
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard WorkerWhen using `raw_ptr<T>` the struct above would look as follows:
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker```cpp
124*6777b538SAndroid Build Coastguard Worker#include "base/memory/raw_ptr.h"
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Workerstruct Example {
127*6777b538SAndroid Build Coastguard Worker  raw_ptr<int> int_ptr;
128*6777b538SAndroid Build Coastguard Worker  raw_ptr<void> void_ptr;
129*6777b538SAndroid Build Coastguard Worker  raw_ptr<SomeClass> object_ptr;
130*6777b538SAndroid Build Coastguard Worker  raw_ptr<const SomeClass> ptr_to_const;
131*6777b538SAndroid Build Coastguard Worker  const raw_ptr<SomeClass> const_ptr;
132*6777b538SAndroid Build Coastguard Worker};
133*6777b538SAndroid Build Coastguard Worker```
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard WorkerIn most cases, only the type in the field declaration needs to change.
136*6777b538SAndroid Build Coastguard WorkerIn particular, `raw_ptr<T>` implements
137*6777b538SAndroid Build Coastguard Worker`operator->`, `operator*` and other operators
138*6777b538SAndroid Build Coastguard Workerthat one expects from a raw pointer.
139*6777b538SAndroid Build Coastguard WorkerCases where other code needs to be modified are described in
140*6777b538SAndroid Build Coastguard Worker[the "Recoverable compile-time problems" section](#Recoverable-compile-time-problems)
141*6777b538SAndroid Build Coastguard Workerbelow.
142*6777b538SAndroid Build Coastguard Worker
143*6777b538SAndroid Build Coastguard Worker## Performance
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker### Performance impact of using |raw_ptr&lt;T&gt;| instead of |T\*|
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard WorkerCompared to a raw C++ pointer, on platforms where ENABLE_BACKUP_REF_PTR_SUPPORT
148*6777b538SAndroid Build Coastguard Workeris on, `raw_ptr<T>` incurs additional runtime
149*6777b538SAndroid Build Coastguard Workeroverhead for initialization, destruction, and assignment (including
150*6777b538SAndroid Build Coastguard Worker`ptr++`, `ptr += ...`, etc.).
151*6777b538SAndroid Build Coastguard WorkerThere is no overhead when dereferencing or extracting a pointer (including
152*6777b538SAndroid Build Coastguard Worker`*ptr`, `ptr->foobar`, `ptr.get()`, or implicit conversions to a raw C++
153*6777b538SAndroid Build Coastguard Workerpointer).
154*6777b538SAndroid Build Coastguard WorkerFinally, `raw_ptr<T>` has exactly the same memory footprint as `T*`
155*6777b538SAndroid Build Coastguard Worker(i.e. `sizeof(raw_ptr<T>) == sizeof(T*)`).
156*6777b538SAndroid Build Coastguard Worker
157*6777b538SAndroid Build Coastguard WorkerOne source of the performance overhead is
158*6777b538SAndroid Build Coastguard Workera check whether a pointer `T*` points to a protected memory pool.
159*6777b538SAndroid Build Coastguard WorkerThis happens in `raw_ptr<T>`'s
160*6777b538SAndroid Build Coastguard Workerconstructor, destructor, and assignment operators.
161*6777b538SAndroid Build Coastguard WorkerIf the pointed memory is unprotected,
162*6777b538SAndroid Build Coastguard Workerthen `raw_ptr<T>` behaves just like a `T*`
163*6777b538SAndroid Build Coastguard Workerand the runtime overhead is limited to that extra check.
164*6777b538SAndroid Build Coastguard Worker(The security protection incurs additional overhead
165*6777b538SAndroid Build Coastguard Workerdescribed in
166*6777b538SAndroid Build Coastguard Worker[the "Performance impact of enabling Use-after-Free protection" section](#Performance-impact-of-enabling-Use-after-Free-protection)
167*6777b538SAndroid Build Coastguard Workerbelow.)
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard WorkerSome additional overhead comes from setting `raw_ptr<T>` to `nullptr`
170*6777b538SAndroid Build Coastguard Workerwhen default-constructed, destructed, or moved. (Yes, we said above to not rely
171*6777b538SAndroid Build Coastguard Workeron it, but to be precise this will always happen when
172*6777b538SAndroid Build Coastguard WorkerENABLE_BACKUP_REF_PTR_SUPPORT is on; no guarantees otherwise.)
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard WorkerDuring
175*6777b538SAndroid Build Coastguard Worker[the "Big Rewrite"](https://groups.google.com/a/chromium.org/g/chromium-dev/c/vAEeVifyf78/m/SkBUc6PhBAAJ)
176*6777b538SAndroid Build Coastguard Workermost Chromium `T*` fields have been rewritten to `raw_ptr<T>`
177*6777b538SAndroid Build Coastguard Worker(excluding fields in Renderer-only code).
178*6777b538SAndroid Build Coastguard WorkerThe cumulative performance impact of such rewrite
179*6777b538SAndroid Build Coastguard Workerhas been measured by earlier A/B binary experiments.
180*6777b538SAndroid Build Coastguard WorkerThere was no measurable impact, except that 32-bit platforms
181*6777b538SAndroid Build Coastguard Workerhave seen a slight increase in jankiness metrics
182*6777b538SAndroid Build Coastguard Worker(for more detailed results see
183*6777b538SAndroid Build Coastguard Worker[the document here](https://docs.google.com/document/d/1MfDT-JQh_UIpSQw3KQttjbQ_drA7zw1gQDwU3cbB6_c/edit?usp=sharing)).
184*6777b538SAndroid Build Coastguard Worker
185*6777b538SAndroid Build Coastguard Worker### Performance impact of enabling Use-after-Free protection {#Performance-impact-of-enabling-Use-after-Free-protection}
186*6777b538SAndroid Build Coastguard Worker
187*6777b538SAndroid Build Coastguard WorkerWhen the Use-after-Free protection is enabled, then `raw_ptr<T>` has some
188*6777b538SAndroid Build Coastguard Workeradditional performance overhead.
189*6777b538SAndroid Build Coastguard Worker
190*6777b538SAndroid Build Coastguard WorkerThe protection can increase memory usage:
191*6777b538SAndroid Build Coastguard Worker- For each memory allocation Chromium's allocator (PartitionAlloc)
192*6777b538SAndroid Build Coastguard Worker  carves out extra 4 bytes. (That doesn't necessarily mean that each allocation
193*6777b538SAndroid Build Coastguard Worker  grows by 4B. Allocation sizes come from predefined buckets, so it's possible
194*6777b538SAndroid Build Coastguard Worker  for an allocation to stay within the same bucket and incur no additional
195*6777b538SAndroid Build Coastguard Worker  overhead, or hop over to the next bucket and incur much higher overhead.)
196*6777b538SAndroid Build Coastguard Worker- Freed memory is quarantined and not available for reuse as long
197*6777b538SAndroid Build Coastguard Worker  as dangling `raw_ptr<T>` pointers exist. (In practice this overhead has been
198*6777b538SAndroid Build Coastguard Worker  observed to be low, but on a couple occasions it led to significant memory
199*6777b538SAndroid Build Coastguard Worker  leaks, fortunately caught early.)
200*6777b538SAndroid Build Coastguard Worker
201*6777b538SAndroid Build Coastguard WorkerThe protection increases runtime costs - `raw_ptr<T>`'s constructor,
202*6777b538SAndroid Build Coastguard Workerdestructor, and assignment operators need to maintain BackupRefPtr's ref-count
203*6777b538SAndroid Build Coastguard Worker(atomic increment/decrement). `ptr++`, `ptr += ...`, etc. don't need to do that,
204*6777b538SAndroid Build Coastguard Workerbut instead have to incur the cost
205*6777b538SAndroid Build Coastguard Workerof verifying that resulting pointer stays within the same allocation (important
206*6777b538SAndroid Build Coastguard Workerfor BRP integrity).
207*6777b538SAndroid Build Coastguard Worker
208*6777b538SAndroid Build Coastguard Worker## When it is okay to continue using raw C++ pointers
209*6777b538SAndroid Build Coastguard Worker
210*6777b538SAndroid Build Coastguard Worker### Unsupported cases leading to compile errors {#Unsupported-cases-leading-to-compile-errors}
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard WorkerContinue to use raw C++ pointers in the following cases, which may otherwise
213*6777b538SAndroid Build Coastguard Workerresult in compile errors:
214*6777b538SAndroid Build Coastguard Worker- Function pointers
215*6777b538SAndroid Build Coastguard Worker- Pointers to Objective-C objects
216*6777b538SAndroid Build Coastguard Worker- Pointer fields in classes/structs that are used as global, static, or
217*6777b538SAndroid Build Coastguard Worker  `thread_local` variables (see more details in the
218*6777b538SAndroid Build Coastguard Worker  [Rewrite exclusion statistics](https://docs.google.com/document/d/1uAsWnwy8HfIJhDPSh1efohnqfGsv2LJmYTRBj0JzZh8/edit#heading=h.dg4eebu87wg9)
219*6777b538SAndroid Build Coastguard Worker  )
220*6777b538SAndroid Build Coastguard Worker- Pointers in unions, as well as pointer fields in classes/structs that are used
221*6777b538SAndroid Build Coastguard Worker  in unions (side note, absl::variant is strongly preferred)
222*6777b538SAndroid Build Coastguard Worker- Code that doesn’t depend on `//base` (including non-Chromium repositories and
223*6777b538SAndroid Build Coastguard Worker  third party libraries)
224*6777b538SAndroid Build Coastguard Worker- Code in `//ppapi`
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker### Pointers to unprotected memory (performance optimization)
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard WorkerUsing `raw_ptr<T>` offers no security benefits (no UaF protection) for pointers
229*6777b538SAndroid Build Coastguard Workerthat don’t point to protected memory (only PartitionAlloc-managed heap allocations
230*6777b538SAndroid Build Coastguard Workerin non-Renderer processes are protected).
231*6777b538SAndroid Build Coastguard WorkerTherefore in the following cases raw C++ pointers may be used instead of
232*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>`:
233*6777b538SAndroid Build Coastguard Worker- Pointer fields that can only point outside PartitionAlloc, including literals,
234*6777b538SAndroid Build Coastguard Worker  stack allocated memory, shared memory, mmap'ed memory, V8/Oilpan/Java heaps,
235*6777b538SAndroid Build Coastguard Worker  TLS, etc.
236*6777b538SAndroid Build Coastguard Worker- `const char*` (and `const wchar_t*`) pointer fields, unless you’re convinced
237*6777b538SAndroid Build Coastguard Worker  they can point to a heap-allocated object, not just a string literal
238*6777b538SAndroid Build Coastguard Worker- Pointer fields in certain renderer code. Specifically, we disallow usage in
239*6777b538SAndroid Build Coastguard Worker
240*6777b538SAndroid Build Coastguard Worker``` none
241*6777b538SAndroid Build Coastguard Workerthird_party/blink/renderer/core/
242*6777b538SAndroid Build Coastguard Workerthird_party/blink/renderer/platform/heap/
243*6777b538SAndroid Build Coastguard Workerthird_party/blink/renderer/platform/wtf/
244*6777b538SAndroid Build Coastguard Worker```
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker### Other perf optimizations
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard WorkerAs a performance optimization, raw C++ pointers may be used instead of
249*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` if it would have a significant
250*6777b538SAndroid Build Coastguard Worker[performance impact](#Performance).
251*6777b538SAndroid Build Coastguard Worker
252*6777b538SAndroid Build Coastguard Worker### Pointers in locations other than fields
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard WorkerUse raw C++ pointers instead of `raw_ptr<T>` in the following scenarios:
255*6777b538SAndroid Build Coastguard Worker- Pointers in local variables and function parameters and return values. This
256*6777b538SAndroid Build Coastguard Worker  includes pointer fields in classes/structs that are used only on the stack.
257*6777b538SAndroid Build Coastguard Worker  (Using `raw_ptr<T>` here would cumulatively lead to performance regression and
258*6777b538SAndroid Build Coastguard Worker  the security benefit of UaF protection is lower for such short-lived
259*6777b538SAndroid Build Coastguard Worker  pointers.)
260*6777b538SAndroid Build Coastguard Worker- Pointer fields in unions. However, note that a much better, modern alternative
261*6777b538SAndroid Build Coastguard Worker  is `absl::variant` + `raw_ptr<T>`. If use of C++ union is absolutely
262*6777b538SAndroid Build Coastguard Worker  unavoidable, prefer a regular C++ pointer: incorrect management of a
263*6777b538SAndroid Build Coastguard Worker  `raw_ptr<T>` field can easily lead to ref-count corruption.
264*6777b538SAndroid Build Coastguard Worker- Pointers whose addresses are used only as identifiers and which are
265*6777b538SAndroid Build Coastguard Worker  never dereferenced (e.g. keys in a map). There is a performance gain
266*6777b538SAndroid Build Coastguard Worker  by not using `raw_ptr` in this case; prefer to use `uintptr_t` to
267*6777b538SAndroid Build Coastguard Worker  emphasize that the entity can dangle and must not be dereferenced. (NOTE,
268*6777b538SAndroid Build Coastguard Worker  this is a dangerous practice irrespective of raw_ptr usage, as there is a risk
269*6777b538SAndroid Build Coastguard Worker  of memory being freed and another pointer allocated with the same address!)
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard WorkerYou don’t have to, but may use `raw_ptr<T>`, in the following scenarios:
272*6777b538SAndroid Build Coastguard Worker- Pointers that are used as an element type of collections/wrappers. E.g.
273*6777b538SAndroid Build Coastguard Worker  `std::vector<T*>` and `std::vector<raw_ptr<T>>` are both okay, but prefer the
274*6777b538SAndroid Build Coastguard Worker  latter if the collection is a class field (note that some of the perf
275*6777b538SAndroid Build Coastguard Worker  optimizations above might still apply and argue for using a raw C++ pointer).
276*6777b538SAndroid Build Coastguard Worker
277*6777b538SAndroid Build Coastguard Worker### Signal Handlers
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` assumes that the allocator's data structures are in a consistent
280*6777b538SAndroid Build Coastguard Workerstate. Signal handlers can interrupt in the middle of an allocation operation;
281*6777b538SAndroid Build Coastguard Workertherefore, `raw_ptr<T>` should not be used in signal handlers.
282*6777b538SAndroid Build Coastguard Worker
283*6777b538SAndroid Build Coastguard Worker## Extra pointer rules {#Extra-pointer-rules}
284*6777b538SAndroid Build Coastguard Worker
285*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` requires following some extra rules compared to a raw C++ pointer:
286*6777b538SAndroid Build Coastguard Worker- Don’t assign invalid, non-null addresses (this includes previously valid and
287*6777b538SAndroid Build Coastguard Worker  now freed memory,
288*6777b538SAndroid Build Coastguard Worker  [Win32 handles](https://crbug.com/1262017), and more). You can only assign an
289*6777b538SAndroid Build Coastguard Worker  address of memory that is valid at the time of assignment. Exceptions:
290*6777b538SAndroid Build Coastguard Worker    - a pointer to the end of a valid allocation (but not even 1 byte further)
291*6777b538SAndroid Build Coastguard Worker    - a pointer to the last page of the address space, e.g. for sentinels like
292*6777b538SAndroid Build Coastguard Worker      `reinterpret_cast<void*>(-1)`
293*6777b538SAndroid Build Coastguard Worker- Don’t initialize or assign `raw_ptr<T>` memory directly
294*6777b538SAndroid Build Coastguard Worker  (e.g. `reinterpret_cast<ClassWithRawPtr*>(buffer)` or
295*6777b538SAndroid Build Coastguard Worker  `memcpy(reinterpret_cast<void*>(&obj_with_raw_ptr), buffer)`.
296*6777b538SAndroid Build Coastguard Worker- Don’t assign to a `raw_ptr<T>` concurrently, even if the same value.
297*6777b538SAndroid Build Coastguard Worker- Don’t rely on moved-from pointers to keep their old value. Unlike raw
298*6777b538SAndroid Build Coastguard Worker  pointers, `raw_ptr<T>` may be cleared upon moving.
299*6777b538SAndroid Build Coastguard Worker- Don't use the pointer after it is destructed. Unlike raw pointers,
300*6777b538SAndroid Build Coastguard Worker  `raw_ptr<T>` may be cleared upon destruction. This may happen e.g. when fields
301*6777b538SAndroid Build Coastguard Worker  are ordered such that the pointer field is destructed before the class field
302*6777b538SAndroid Build Coastguard Worker  whose destructor uses that pointer field (e.g. see
303*6777b538SAndroid Build Coastguard Worker  [Esoteric Issues](https://docs.google.com/document/d/14Ol_adOdNpy4Ge-XReI7CXNKMzs_LL5vucDQIERDQyg/edit#heading=h.yoba1l8bnfmv)).
304*6777b538SAndroid Build Coastguard Worker- Don’t assign to a `raw_ptr<T>` until its constructor has run. This may happen
305*6777b538SAndroid Build Coastguard Worker  when a base class’s constructor uses a not-yet-initialized field of a derived
306*6777b538SAndroid Build Coastguard Worker  class (e.g. see
307*6777b538SAndroid Build Coastguard Worker  [Applying MiraclePtr](https://docs.google.com/document/d/1cnpd5Rwesq7DCZiD8FIJfPGHvQN3-Gul6xib_4hwfBg/edit?ts=5ed2d317#heading=h.4ry5d9a6fuxs)).
308*6777b538SAndroid Build Coastguard Worker
309*6777b538SAndroid Build Coastguard WorkerSome of these would result in undefined behavior (UB) even in the world without
310*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` (e.g. see
311*6777b538SAndroid Build Coastguard Worker[Field destruction order](https://groups.google.com/a/chromium.org/g/memory-safety-dev/c/3sEmSnFc61I/m/ZtaeWGslAQAJ)),
312*6777b538SAndroid Build Coastguard Workerbut you’d likely get away without any consequences. In the `raw_ptr<T>` world,
313*6777b538SAndroid Build Coastguard Workeran obscure crash may occur. Those crashes often manifest themselves as SEGV or
314*6777b538SAndroid Build Coastguard Worker`CHECK` inside `RawPtrBackupRefImpl::AcquireInternal()` or
315*6777b538SAndroid Build Coastguard Worker`RawPtrBackupRefImpl::ReleaseInternal()`, but you may also experience memory
316*6777b538SAndroid Build Coastguard Workercorruption or a silent drop of UaF protection.
317*6777b538SAndroid Build Coastguard Worker
318*6777b538SAndroid Build Coastguard Worker## Pointer Annotations
319*6777b538SAndroid Build Coastguard Worker
320*6777b538SAndroid Build Coastguard Worker### The AllowPtrArithmetic trait
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard WorkerIn an ideal world, a raw_ptr would point to a single object, rather than to
323*6777b538SAndroid Build Coastguard Workera C-style array of objects accessed via pointer arithmetic, since the latter
324*6777b538SAndroid Build Coastguard Workeris best handled via a C++ construct such as base::span<> or std::vector<>.
325*6777b538SAndroid Build Coastguard Workerraw_ptrs upon which such operations are performed and for which conversion is
326*6777b538SAndroid Build Coastguard Workerdesirable have been tagged with the AllowPtrArithmetic trait. That all such
327*6777b538SAndroid Build Coastguard Workerpointer are tagged can be enforced by setting the GN build arg
328*6777b538SAndroid Build Coastguard Workerenable_pointer_arithmetic_trait_check=true.
329*6777b538SAndroid Build Coastguard Worker
330*6777b538SAndroid Build Coastguard Worker### The AllowUninitialized trait
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard WorkerWhen building Chromium, raw_ptrs are always nullptr initialized, either as
333*6777b538SAndroid Build Coastguard Workerthe result of specific implementation that requires it (e.g. BackupRefPtr),
334*6777b538SAndroid Build Coastguard Workeror as the result of build flags (to enforce consistency). However, we provide
335*6777b538SAndroid Build Coastguard Workeran opt-out to allow third-party code to skip this step (where possible). Use
336*6777b538SAndroid Build Coastguard Workerthis trait sparingly.
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker## Recoverable compile-time problems {#Recoverable-compile-time-problems}
339*6777b538SAndroid Build Coastguard Worker
340*6777b538SAndroid Build Coastguard Worker### Explicit |raw_ptr.get()| might be needed
341*6777b538SAndroid Build Coastguard Worker
342*6777b538SAndroid Build Coastguard WorkerIf a raw pointer is needed, but an implicit cast from `raw_ptr<SomeClass>` to
343*6777b538SAndroid Build Coastguard Worker`SomeClass*` doesn't work, then the raw pointer needs to be obtained by explicitly
344*6777b538SAndroid Build Coastguard Workercalling `.get()`. Examples:
345*6777b538SAndroid Build Coastguard Worker- `auto* raw_ptr_var = wrapped_ptr_.get()` (`auto*` requires the initializer to
346*6777b538SAndroid Build Coastguard Worker  be a raw pointer)
347*6777b538SAndroid Build Coastguard Worker    - Alternatively you can change `auto*` to `auto&`. Avoid using `auto` as it’ll
348*6777b538SAndroid Build Coastguard Worker      copy the pointer, which incurs a performance overhead.
349*6777b538SAndroid Build Coastguard Worker- `return condition ? raw_ptr : wrapped_ptr_.get();` (ternary operator needs
350*6777b538SAndroid Build Coastguard Worker  identical types in both branches)
351*6777b538SAndroid Build Coastguard Worker- `TemplatedFunction(wrapped_ptr_.get());` (implicit cast doesn't kick in for
352*6777b538SAndroid Build Coastguard Worker  `T*` arguments in templates)
353*6777b538SAndroid Build Coastguard Worker- `printf("%p", wrapped_ptr_.get());` (can't pass class type arguments to
354*6777b538SAndroid Build Coastguard Worker  variadic functions)
355*6777b538SAndroid Build Coastguard Worker- `reinterpret_cast<SomeClass*>(wrapped_ptr_.get())` (`const_cast` and
356*6777b538SAndroid Build Coastguard Worker  `reinterpret_cast` sometimes require their argument to be a raw pointer;
357*6777b538SAndroid Build Coastguard Worker  `static_cast` should "Just Work")
358*6777b538SAndroid Build Coastguard Worker- `T2 t2 = t1_wrapped_ptr_.get();` (where there is an implicit conversion
359*6777b538SAndroid Build Coastguard Worker  constructor `T2(T1*)` the compiler can handle one implicit conversion, but not
360*6777b538SAndroid Build Coastguard Worker  two)
361*6777b538SAndroid Build Coastguard Worker- In general, when type is inferred by a compiler and then used in a context
362*6777b538SAndroid Build Coastguard Worker  where a pointer is expected.
363*6777b538SAndroid Build Coastguard Worker
364*6777b538SAndroid Build Coastguard Worker### Out-of-line constructor/destructor might be needed
365*6777b538SAndroid Build Coastguard Worker
366*6777b538SAndroid Build Coastguard WorkerOut-of-line constructor/destructor may be newly required by the chromium style
367*6777b538SAndroid Build Coastguard Workerclang plugin.  Error examples:
368*6777b538SAndroid Build Coastguard Worker- `error: [chromium-style] Complex class/struct needs an explicit out-of-line
369*6777b538SAndroid Build Coastguard Worker  destructor.`
370*6777b538SAndroid Build Coastguard Worker- `error: [chromium-style] Complex class/struct needs an explicit out-of-line
371*6777b538SAndroid Build Coastguard Worker  constructor.`
372*6777b538SAndroid Build Coastguard Worker
373*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` uses a non-trivial constructor/destructor, so classes that used to
374*6777b538SAndroid Build Coastguard Workerbe POD or have a trivial destructor may require an out-of-line
375*6777b538SAndroid Build Coastguard Workerconstructor/destructor to satisfy the chromium style clang plugin.
376*6777b538SAndroid Build Coastguard Worker
377*6777b538SAndroid Build Coastguard Worker
378*6777b538SAndroid Build Coastguard Worker### In-out arguments need to be refactored
379*6777b538SAndroid Build Coastguard Worker
380*6777b538SAndroid Build Coastguard WorkerDue to implementation difficulties,
381*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` doesn't support an address-of operator.
382*6777b538SAndroid Build Coastguard WorkerThis means that the following code will not compile:
383*6777b538SAndroid Build Coastguard Worker
384*6777b538SAndroid Build Coastguard Worker```cpp
385*6777b538SAndroid Build Coastguard Workervoid GetSomeClassPtr(SomeClass** out_arg) {
386*6777b538SAndroid Build Coastguard Worker  *out_arg = ...;
387*6777b538SAndroid Build Coastguard Worker}
388*6777b538SAndroid Build Coastguard Worker
389*6777b538SAndroid Build Coastguard Workerstruct MyStruct {
390*6777b538SAndroid Build Coastguard Worker  void Example() {
391*6777b538SAndroid Build Coastguard Worker    GetSomeClassPtr(&wrapped_ptr_);  // <- won't compile
392*6777b538SAndroid Build Coastguard Worker  }
393*6777b538SAndroid Build Coastguard Worker
394*6777b538SAndroid Build Coastguard Worker  raw_ptr<SomeClass> wrapped_ptr_;
395*6777b538SAndroid Build Coastguard Worker};
396*6777b538SAndroid Build Coastguard Worker```
397*6777b538SAndroid Build Coastguard Worker
398*6777b538SAndroid Build Coastguard WorkerThe typical fix is to change the type of the out argument
399*6777b538SAndroid Build Coastguard Worker(see also [an example CL here](https://crrev.com/c/4545743)):
400*6777b538SAndroid Build Coastguard Worker
401*6777b538SAndroid Build Coastguard Worker```cpp
402*6777b538SAndroid Build Coastguard Workervoid GetSomeClassPtr(raw_ptr<SomeClass>* out_arg) {
403*6777b538SAndroid Build Coastguard Worker  *out_arg = ...;
404*6777b538SAndroid Build Coastguard Worker}
405*6777b538SAndroid Build Coastguard Worker```
406*6777b538SAndroid Build Coastguard Worker
407*6777b538SAndroid Build Coastguard WorkerSimilarly this code:
408*6777b538SAndroid Build Coastguard Worker
409*6777b538SAndroid Build Coastguard Worker```cpp
410*6777b538SAndroid Build Coastguard Workervoid FillPtr(SomeClass*& out_arg) {
411*6777b538SAndroid Build Coastguard Worker  out_arg = ...;
412*6777b538SAndroid Build Coastguard Worker}
413*6777b538SAndroid Build Coastguard Worker```
414*6777b538SAndroid Build Coastguard Worker
415*6777b538SAndroid Build Coastguard Workerwould have to be changed to this:
416*6777b538SAndroid Build Coastguard Worker
417*6777b538SAndroid Build Coastguard Worker```cpp
418*6777b538SAndroid Build Coastguard Workervoid FillPtr(raw_ptr<SomeClass>& out_arg) {
419*6777b538SAndroid Build Coastguard Worker  out_arg = ...;
420*6777b538SAndroid Build Coastguard Worker}
421*6777b538SAndroid Build Coastguard Worker```
422*6777b538SAndroid Build Coastguard Worker
423*6777b538SAndroid Build Coastguard WorkerSimilarly this code:
424*6777b538SAndroid Build Coastguard Worker
425*6777b538SAndroid Build Coastguard Worker```cpp
426*6777b538SAndroid Build Coastguard WorkerSomeClass*& GetPtr() {
427*6777b538SAndroid Build Coastguard Worker  return wrapper_ptr_;
428*6777b538SAndroid Build Coastguard Worker}
429*6777b538SAndroid Build Coastguard Worker```
430*6777b538SAndroid Build Coastguard Worker
431*6777b538SAndroid Build Coastguard Workerwould have to be changed to this:
432*6777b538SAndroid Build Coastguard Worker
433*6777b538SAndroid Build Coastguard Worker```cpp
434*6777b538SAndroid Build Coastguard Workerraw_ptr<SomeClass>& GetPtr() {
435*6777b538SAndroid Build Coastguard Worker  return wrapper_ptr_;
436*6777b538SAndroid Build Coastguard Worker}
437*6777b538SAndroid Build Coastguard Worker```
438*6777b538SAndroid Build Coastguard Worker
439*6777b538SAndroid Build Coastguard Worker
440*6777b538SAndroid Build Coastguard WorkerIn case you cannot refactor the in-out arguments (e.g. third party library), you
441*6777b538SAndroid Build Coastguard Workermay use `raw_ptr.AsEphemeralRawAddr()` to obtain *extremely* short-lived
442*6777b538SAndroid Build Coastguard Worker`T**` or `T*&`. You should not treat `T**` obtained via
443*6777b538SAndroid Build Coastguard Worker`raw_ptr.AsEphemeralRawAddr()` as a normal pointer pointer, and must follow
444*6777b538SAndroid Build Coastguard Workerthese requirements.
445*6777b538SAndroid Build Coastguard Worker
446*6777b538SAndroid Build Coastguard Worker- Do NOT store `T**` or `T*&` anywhere, even as a local variable.
447*6777b538SAndroid Build Coastguard Worker  - It will become invalid very quickly and can cause dangling pointer issue
448*6777b538SAndroid Build Coastguard Worker- Do NOT use `raw_ptr<T>`, `T**` or `T*&` multiple times within an expression.
449*6777b538SAndroid Build Coastguard Worker  - The implementation assumes raw_ptr<T> is never accessed when `T**` or `T*&`
450*6777b538SAndroid Build Coastguard Worker    is alive.
451*6777b538SAndroid Build Coastguard Worker
452*6777b538SAndroid Build Coastguard Worker```cpp
453*6777b538SAndroid Build Coastguard Workervoid GetSomeClassPtr(SomeClass** out_arg) {
454*6777b538SAndroid Build Coastguard Worker  *out_arg = ...;
455*6777b538SAndroid Build Coastguard Worker}
456*6777b538SAndroid Build Coastguard Workervoid FillPtr(SomeClass*& out_arg) {
457*6777b538SAndroid Build Coastguard Worker  out_arg = ...;
458*6777b538SAndroid Build Coastguard Worker}
459*6777b538SAndroid Build Coastguard Workervoid Foo() {
460*6777b538SAndroid Build Coastguard Worker  raw_ptr<SomeClass> ptr;
461*6777b538SAndroid Build Coastguard Worker  GetSomeClassPtr(&ptr.AsEphemeralRawAddr());
462*6777b538SAndroid Build Coastguard Worker  FillPtr(ptr.AsEphemeralRawAddr()); // Implicitly converted into |SomeClass*&|.
463*6777b538SAndroid Build Coastguard Worker}
464*6777b538SAndroid Build Coastguard Worker```
465*6777b538SAndroid Build Coastguard Worker
466*6777b538SAndroid Build Coastguard WorkerTechnically, `raw_ptr.AsEphemeralRawAddr()` generates a temporary instance of
467*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>::EphemeralRawAddr`, which holds a temporary copy of `T*`.
468*6777b538SAndroid Build Coastguard Worker`T**` and `T*&` points to a copied version of the original pointer and
469*6777b538SAndroid Build Coastguard Workerany modification made via `T**` or `T*&` is written back on destruction of
470*6777b538SAndroid Build Coastguard Worker`EphemeralRawAddr` instance.
471*6777b538SAndroid Build Coastguard WorkerC++ guarantees a temporary object returned by `raw_ptr.AsEphemeralRawAddr()`
472*6777b538SAndroid Build Coastguard Workerlives until completion of evaluation of "full-expression" (i.e. the outermost
473*6777b538SAndroid Build Coastguard Workerexpression). This makes it possible to use `T**` and `T*&` within single
474*6777b538SAndroid Build Coastguard Workerexpression like in-out param.
475*6777b538SAndroid Build Coastguard Worker
476*6777b538SAndroid Build Coastguard Worker```cpp
477*6777b538SAndroid Build Coastguard Workerstruct EphemeralRawAddr {
478*6777b538SAndroid Build Coastguard Worker  EphemeralRawAddr(raw_ptr& ptr): copy(ptr.get()), original(ptr) {}
479*6777b538SAndroid Build Coastguard Worker  ~EphemeralRawAddr() {
480*6777b538SAndroid Build Coastguard Worker    original = copy;
481*6777b538SAndroid Build Coastguard Worker    copy = nullptr;
482*6777b538SAndroid Build Coastguard Worker  }
483*6777b538SAndroid Build Coastguard Worker
484*6777b538SAndroid Build Coastguard Worker  T** operator&() { return &copy; }
485*6777b538SAndroid Build Coastguard Worker  operator T*&() { return copy; }
486*6777b538SAndroid Build Coastguard Worker
487*6777b538SAndroid Build Coastguard Worker  T* copy;
488*6777b538SAndroid Build Coastguard Worker  raw_ptr& original;  // Original pointer.
489*6777b538SAndroid Build Coastguard Worker};
490*6777b538SAndroid Build Coastguard Worker```
491*6777b538SAndroid Build Coastguard Worker
492*6777b538SAndroid Build Coastguard Worker
493*6777b538SAndroid Build Coastguard Worker### Modern |nullptr| is required
494*6777b538SAndroid Build Coastguard Worker
495*6777b538SAndroid Build Coastguard WorkerAs recommended by the Google C++ Style Guide,
496*6777b538SAndroid Build Coastguard Worker[use nullptr instead of NULL](https://google.github.io/styleguide/cppguide.html#0_and_nullptr/NULL) -
497*6777b538SAndroid Build Coastguard Workerthe latter might result in compile-time errors when used with `raw_ptr<T>`.
498*6777b538SAndroid Build Coastguard Worker
499*6777b538SAndroid Build Coastguard WorkerExample:
500*6777b538SAndroid Build Coastguard Worker
501*6777b538SAndroid Build Coastguard Worker```cpp
502*6777b538SAndroid Build Coastguard Workerstruct SomeStruct {
503*6777b538SAndroid Build Coastguard Worker  raw_ptr<int> ptr_field;
504*6777b538SAndroid Build Coastguard Worker};
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Workervoid bar() {
507*6777b538SAndroid Build Coastguard Worker  SomeStruct some_struct;
508*6777b538SAndroid Build Coastguard Worker  some_struct.ptr_field = NULL;
509*6777b538SAndroid Build Coastguard Worker}
510*6777b538SAndroid Build Coastguard Worker```
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard WorkerError:
513*6777b538SAndroid Build Coastguard Worker```err
514*6777b538SAndroid Build Coastguard Worker../../base/memory/checked_ptr_unittest.cc:139:25: error: use of overloaded
515*6777b538SAndroid Build Coastguard Workeroperator '=' is ambiguous (with operand types raw_ptr<int>' and 'long')
516*6777b538SAndroid Build Coastguard Worker  some_struct.ptr_field = NULL;
517*6777b538SAndroid Build Coastguard Worker  ~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
518*6777b538SAndroid Build Coastguard Worker../../base/memory/raw_ptr.h:369:29: note: candidate function
519*6777b538SAndroid Build Coastguard Worker  ALWAYS_INLINE raw_ptr& operator=(std::nullptr_t) noexcept {
520*6777b538SAndroid Build Coastguard Worker                         ^
521*6777b538SAndroid Build Coastguard Worker../../base/memory/raw_ptr.h:374:29: note: candidate function
522*6777b538SAndroid Build Coastguard Worker  ALWAYS_INLINE raw_ptr& operator=(T* p)
523*6777b538SAndroid Build Coastguard Worker                         noexcept {
524*6777b538SAndroid Build Coastguard Worker```
525*6777b538SAndroid Build Coastguard Worker
526*6777b538SAndroid Build Coastguard Worker### [rare] Explicit overload or template specialization for |raw_ptr&lt;T&gt;|
527*6777b538SAndroid Build Coastguard Worker
528*6777b538SAndroid Build Coastguard WorkerIn rare cases, the default template code won’t compile when `raw_ptr<...>` is
529*6777b538SAndroid Build Coastguard Workersubstituted for a template argument.  In such cases, it might be necessary to
530*6777b538SAndroid Build Coastguard Workerprovide an explicit overload or template specialization for `raw_ptr<T>`.
531*6777b538SAndroid Build Coastguard Worker
532*6777b538SAndroid Build Coastguard WorkerExample (more details in
533*6777b538SAndroid Build Coastguard Worker[Applying MiraclePtr](https://docs.google.com/document/d/1cnpd5Rwesq7DCZiD8FIJfPGHvQN3-Gul6xib_4hwfBg/edit?ts=5ed2d317#heading=h.o2pf3fg0zzf) and the
534*6777b538SAndroid Build Coastguard Worker[Add CheckedPtr support for cbor_extract::Element](https://chromium-review.googlesource.com/c/chromium/src/+/2224954)
535*6777b538SAndroid Build Coastguard WorkerCL):
536*6777b538SAndroid Build Coastguard Worker
537*6777b538SAndroid Build Coastguard Worker```cpp
538*6777b538SAndroid Build Coastguard Worker// An explicit overload (taking raw_ptr<T> as an argument)
539*6777b538SAndroid Build Coastguard Worker// was needed below:
540*6777b538SAndroid Build Coastguard Workertemplate <typename S>
541*6777b538SAndroid Build Coastguard Workerconstexpr StepOrByte<S> Element(
542*6777b538SAndroid Build Coastguard Worker    const Is required,
543*6777b538SAndroid Build Coastguard Worker    raw_ptr<const std::string> S::*member,  // <- HERE
544*6777b538SAndroid Build Coastguard Worker    uintptr_t offset) {
545*6777b538SAndroid Build Coastguard Worker  return ElementImpl<S>(required, offset, internal::Type::kString);
546*6777b538SAndroid Build Coastguard Worker}
547*6777b538SAndroid Build Coastguard Worker```
548*6777b538SAndroid Build Coastguard Worker
549*6777b538SAndroid Build Coastguard Worker## AddressSanitizer support
550*6777b538SAndroid Build Coastguard Worker
551*6777b538SAndroid Build Coastguard WorkerFor years, AddressSanitizer has been the main tool for diagnosing memory
552*6777b538SAndroid Build Coastguard Workercorruption issues in Chromium. MiraclePtr alters the security properties of some
553*6777b538SAndroid Build Coastguard Workerof some such issues, so ideally it should be integrated with ASan. That way an
554*6777b538SAndroid Build Coastguard Workerengineer would be able to check whether a given use-after-free vulnerability is
555*6777b538SAndroid Build Coastguard Workercovered by the protection without having to switch between ASan and non-ASan
556*6777b538SAndroid Build Coastguard Workerbuilds.
557*6777b538SAndroid Build Coastguard Worker
558*6777b538SAndroid Build Coastguard WorkerUnfortunately, MiraclePtr relies heavily on PartitionAlloc, and ASan needs its
559*6777b538SAndroid Build Coastguard Workerown allocator to work. As a result, the default implementation of `raw_ptr<T>`
560*6777b538SAndroid Build Coastguard Workercan't be used with ASan builds. Instead, a special version of `raw_ptr<T>` has
561*6777b538SAndroid Build Coastguard Workerbeen implemented, which is based on the ASan quarantine and acts as a
562*6777b538SAndroid Build Coastguard Workersufficiently close approximation for diagnostic purposes. At crash time, the
563*6777b538SAndroid Build Coastguard Workertool will tell the user if the dangling pointer access would have been protected
564*6777b538SAndroid Build Coastguard Workerby MiraclePtr *in a regular build*.
565*6777b538SAndroid Build Coastguard Worker
566*6777b538SAndroid Build Coastguard WorkerYou can configure the diagnostic tool by modifying the parameters of the feature
567*6777b538SAndroid Build Coastguard Workerflag `PartitionAllocBackupRefPtr`. For example, launching Chromium as follows:
568*6777b538SAndroid Build Coastguard Worker
569*6777b538SAndroid Build Coastguard Worker```
570*6777b538SAndroid Build Coastguard Workerpath/to/chrome --enable-features=PartitionAllocBackupRefPtr:enabled-processes/browser-only/asan-enable-dereference-check/true/asan-enable-extraction-check/true/asan-enable-instantiation-check/true
571*6777b538SAndroid Build Coastguard Worker```
572*6777b538SAndroid Build Coastguard Worker
573*6777b538SAndroid Build Coastguard Workeractivates all available checks in the browser process.
574*6777b538SAndroid Build Coastguard Worker
575*6777b538SAndroid Build Coastguard Worker### Available checks
576*6777b538SAndroid Build Coastguard Worker
577*6777b538SAndroid Build Coastguard WorkerMiraclePtr provides ASan users with three kinds of security checks, which differ
578*6777b538SAndroid Build Coastguard Workerin when a particular check occurs:
579*6777b538SAndroid Build Coastguard Worker
580*6777b538SAndroid Build Coastguard Worker#### Dereference
581*6777b538SAndroid Build Coastguard Worker
582*6777b538SAndroid Build Coastguard WorkerThis is the basic check type that helps diagnose regular heap-use-after-free
583*6777b538SAndroid Build Coastguard Workerbugs. It's enabled by default.
584*6777b538SAndroid Build Coastguard Worker
585*6777b538SAndroid Build Coastguard Worker#### Extraction
586*6777b538SAndroid Build Coastguard Worker
587*6777b538SAndroid Build Coastguard WorkerThe user will be warned if a dangling pointer is extracted from a `raw_ptr<T>`
588*6777b538SAndroid Build Coastguard Workervariable. If the pointer is then dereferenced, an ASan error report will follow.
589*6777b538SAndroid Build Coastguard WorkerIn some cases, extra work on the reproduction case is required to reach the
590*6777b538SAndroid Build Coastguard Workerfaulty memory access. However, even without memory corruption, relying on the
591*6777b538SAndroid Build Coastguard Workervalue of a dangling pointer may lead to problems. For example, it's a common
592*6777b538SAndroid Build Coastguard Worker(anti-)pattern in Chromium to use a raw pointer as a key in a container.
593*6777b538SAndroid Build Coastguard WorkerConsider the following example:
594*6777b538SAndroid Build Coastguard Worker
595*6777b538SAndroid Build Coastguard Worker```
596*6777b538SAndroid Build Coastguard Workerstd::map<T*, std::unique_ptr<Ext>> g_map;
597*6777b538SAndroid Build Coastguard Worker
598*6777b538SAndroid Build Coastguard Workerstruct A {
599*6777b538SAndroid Build Coastguard Worker  A() {
600*6777b538SAndroid Build Coastguard Worker    g_map[this] = std::make_unique<Ext>(this);
601*6777b538SAndroid Build Coastguard Worker  }
602*6777b538SAndroid Build Coastguard Worker
603*6777b538SAndroid Build Coastguard Worker  ~A() {
604*6777b538SAndroid Build Coastguard Worker    g_map.erase(this);
605*6777b538SAndroid Build Coastguard Worker  }
606*6777b538SAndroid Build Coastguard Worker};
607*6777b538SAndroid Build Coastguard Worker
608*6777b538SAndroid Build Coastguard Workerraw_ptr<A> dangling = new A;
609*6777b538SAndroid Build Coastguard Worker// ...
610*6777b538SAndroid Build Coastguard Workerdelete dangling.get();
611*6777b538SAndroid Build Coastguard WorkerA* replacement = new A;
612*6777b538SAndroid Build Coastguard Worker// ...
613*6777b538SAndroid Build Coastguard Workerauto it = g_map.find(dangling);
614*6777b538SAndroid Build Coastguard Workerif (it == g_map.end())
615*6777b538SAndroid Build Coastguard Worker  return 0;
616*6777b538SAndroid Build Coastguard Workerit->second.DoStuff();
617*6777b538SAndroid Build Coastguard Worker```
618*6777b538SAndroid Build Coastguard Worker
619*6777b538SAndroid Build Coastguard WorkerDepending on whether the allocator reuses the same memory region for the second
620*6777b538SAndroid Build Coastguard Worker`A` object, the program may inadvertently call `DoStuff()` on the wrong `Ext`
621*6777b538SAndroid Build Coastguard Workerinstance. This, in turn, may corrupt the state of the program or bypass security
622*6777b538SAndroid Build Coastguard Workercontrols if the two `A` objects belong to different security contexts.
623*6777b538SAndroid Build Coastguard Worker
624*6777b538SAndroid Build Coastguard WorkerGiven the proportion of false positives reported in the mode, it is disabled by
625*6777b538SAndroid Build Coastguard Workerdefault. It's mainly intended to be used by security researchers who are willing
626*6777b538SAndroid Build Coastguard Workerto spend a significant amount of time investigating these early warnings.
627*6777b538SAndroid Build Coastguard Worker
628*6777b538SAndroid Build Coastguard Worker#### Instantiation
629*6777b538SAndroid Build Coastguard Worker
630*6777b538SAndroid Build Coastguard WorkerThis check detects violations of the rule that when instantiating a `raw_ptr<T>`
631*6777b538SAndroid Build Coastguard Workerfrom a `T*` , it is only allowed if the `T*` is a valid (i.e. not dangling)
632*6777b538SAndroid Build Coastguard Workerpointer. This rule exists to help avoid an issue called "pointer laundering"
633*6777b538SAndroid Build Coastguard Workerwhich can result in unsafe `raw_ptr<T>` instances that point to memory that is
634*6777b538SAndroid Build Coastguard Workerno longer in quarantine. This is important, since subsequent use of these
635*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` might appear to be safe.
636*6777b538SAndroid Build Coastguard Worker
637*6777b538SAndroid Build Coastguard WorkerIn order for "pointer laundering" to occur, we need (1) a dangling `T*`
638*6777b538SAndroid Build Coastguard Worker(pointing to memory that has been freed) to be assigned to a `raw_ptr<T>`, while
639*6777b538SAndroid Build Coastguard Worker(2) there is no other `raw_ptr<T>` pointing to the same object/allocation at the
640*6777b538SAndroid Build Coastguard Workertime of assignment.
641*6777b538SAndroid Build Coastguard Worker
642*6777b538SAndroid Build Coastguard WorkerThe check only detects (1), a dangling `T*` being assigned to a `raw_ptr<T>`, so
643*6777b538SAndroid Build Coastguard Workerin order to determine whether "pointer laundering" has occurred, we need to
644*6777b538SAndroid Build Coastguard Workerdetermine whether (2) could plausibly occur, not just in the specific
645*6777b538SAndroid Build Coastguard Workerreproduction testcase, but in the more general case.
646*6777b538SAndroid Build Coastguard Worker
647*6777b538SAndroid Build Coastguard WorkerIn the absence of thorough reasoning about (2), the assumption here should be
648*6777b538SAndroid Build Coastguard Workerthat any failure of this check is a security issue of the same severity as an
649*6777b538SAndroid Build Coastguard Workerunprotected use-after-free.
650*6777b538SAndroid Build Coastguard Worker
651*6777b538SAndroid Build Coastguard Worker### Protection status
652*6777b538SAndroid Build Coastguard Worker
653*6777b538SAndroid Build Coastguard WorkerWhen ASan generates a heap-use-after-free report, it will include a new section
654*6777b538SAndroid Build Coastguard Workernear the bottom, which starts with the line `MiraclePtr Status: <status>`. At
655*6777b538SAndroid Build Coastguard Workerthe moment, it has three possible options:
656*6777b538SAndroid Build Coastguard Worker
657*6777b538SAndroid Build Coastguard Worker#### Protected
658*6777b538SAndroid Build Coastguard Worker
659*6777b538SAndroid Build Coastguard WorkerThe system is sufficiently confident that MiraclePtr makes the discovered issue
660*6777b538SAndroid Build Coastguard Workerunexploitable. In the future, the security severity of such bugs will be
661*6777b538SAndroid Build Coastguard Workerreduced.
662*6777b538SAndroid Build Coastguard Worker
663*6777b538SAndroid Build Coastguard Worker#### Manual analysis required
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard WorkerDangling pointer extraction was detected before the crash, but there might be
666*6777b538SAndroid Build Coastguard Workerextra code between the extraction and dereference. Most of the time, the code in
667*6777b538SAndroid Build Coastguard Workerquestion will look similar to the following:
668*6777b538SAndroid Build Coastguard Worker
669*6777b538SAndroid Build Coastguard Worker```
670*6777b538SAndroid Build Coastguard Workerstruct A {
671*6777b538SAndroid Build Coastguard Worker  raw_ptr<T> dangling_;
672*6777b538SAndroid Build Coastguard Worker};
673*6777b538SAndroid Build Coastguard Worker
674*6777b538SAndroid Build Coastguard Workervoid trigger(A* a) {
675*6777b538SAndroid Build Coastguard Worker  // ...
676*6777b538SAndroid Build Coastguard Worker  T* local = a->dangling_;
677*6777b538SAndroid Build Coastguard Worker  DoStuff();
678*6777b538SAndroid Build Coastguard Worker  local->DoOtherStuff();
679*6777b538SAndroid Build Coastguard Worker  // ...
680*6777b538SAndroid Build Coastguard Worker}
681*6777b538SAndroid Build Coastguard Worker```
682*6777b538SAndroid Build Coastguard Worker
683*6777b538SAndroid Build Coastguard WorkerIn this scenario, even though `dangling_` points to freed memory, that memory
684*6777b538SAndroid Build Coastguard Workeris protected and will stay in quarantine until `dangling_` (and all other
685*6777b538SAndroid Build Coastguard Worker`raw_ptr<T>` variables pointing to the same region) changes its value or gets
686*6777b538SAndroid Build Coastguard Workerdestroyed. Therefore, the expression `a_->dangling->DoOtherStuff()` wouldn't
687*6777b538SAndroid Build Coastguard Workertrigger an exploitable use-after-free.
688*6777b538SAndroid Build Coastguard Worker
689*6777b538SAndroid Build Coastguard WorkerYou will need to make sure that `DoStuff()` is sufficiently trivial and can't
690*6777b538SAndroid Build Coastguard Worker(not only for the particular reproduction case, but *even in principle*) make
691*6777b538SAndroid Build Coastguard Worker`dangling_` change its value or get destroyed. If that's the case, the
692*6777b538SAndroid Build Coastguard Worker`DoOtherStuff()` call may be considered protected. The tool will provide you
693*6777b538SAndroid Build Coastguard Workerwith the stack trace for both the extraction and dereference events.
694*6777b538SAndroid Build Coastguard Worker
695*6777b538SAndroid Build Coastguard Worker#### Not protected
696*6777b538SAndroid Build Coastguard Worker
697*6777b538SAndroid Build Coastguard WorkerThe dangling `T*` doesn't appear to originate from a `raw_ptr<T>` variable,
698*6777b538SAndroid Build Coastguard Workerwhich means MiraclePtr can't prevent this issue from being exploited. In
699*6777b538SAndroid Build Coastguard Workerpractice, there may still be a `raw_ptr<T>` in a different part of the code that
700*6777b538SAndroid Build Coastguard Workerprotects the same allocation indirectly, but such protection won't be considered
701*6777b538SAndroid Build Coastguard Workerrobust enough to impact security-related decisions.
702*6777b538SAndroid Build Coastguard Worker
703*6777b538SAndroid Build Coastguard Worker### Limitations
704*6777b538SAndroid Build Coastguard Worker
705*6777b538SAndroid Build Coastguard WorkerThe main limitation of MiraclePtr in ASan builds is the main limitation of ASan
706*6777b538SAndroid Build Coastguard Workeritself: the capacity of the quarantine is limited. Eventually, every allocation
707*6777b538SAndroid Build Coastguard Workerin quarantine will get reused regardless of whether there are still references
708*6777b538SAndroid Build Coastguard Workerto it.
709*6777b538SAndroid Build Coastguard Worker
710*6777b538SAndroid Build Coastguard WorkerIn the context of MiraclePtr combined with ASan, it's a problem when:
711*6777b538SAndroid Build Coastguard Worker
712*6777b538SAndroid Build Coastguard Worker1. A heap allocation that isn't supported by MiraclePtr is made. At the moment,
713*6777b538SAndroid Build Coastguard Worker   the only such class is allocations made early during the process startup
714*6777b538SAndroid Build Coastguard Worker   before MiraclePtr can be activated.
715*6777b538SAndroid Build Coastguard Worker2. Its address is assigned to a `raw_ptr<T>` variable.
716*6777b538SAndroid Build Coastguard Worker3. The allocation gets freed.
717*6777b538SAndroid Build Coastguard Worker4. A new allocation is made in the same memory region as the first one, but this
718*6777b538SAndroid Build Coastguard Worker   time it is supported.
719*6777b538SAndroid Build Coastguard Worker5. The second allocation gets freed.
720*6777b538SAndroid Build Coastguard Worker6. The `raw_ptr<T>` variable is accessed.
721*6777b538SAndroid Build Coastguard Worker
722*6777b538SAndroid Build Coastguard WorkerIn this case, MiraclePtr will incorrectly assume the memory access is protected.
723*6777b538SAndroid Build Coastguard WorkerLuckily, considering the small number of unprotected allocations in Chromium,
724*6777b538SAndroid Build Coastguard Workerthe size of the quarantine, and the fact that most reproduction cases take
725*6777b538SAndroid Build Coastguard Workerrelatively short time to run, the odds of this happening are very low.
726*6777b538SAndroid Build Coastguard Worker
727*6777b538SAndroid Build Coastguard WorkerThe problem is relatively easy to spot if you look at the ASan report: the
728*6777b538SAndroid Build Coastguard Workerallocation and deallocation stack traces won't be consistent across runs and
729*6777b538SAndroid Build Coastguard Workerthe allocation type won't match the use stack trace.
730*6777b538SAndroid Build Coastguard Worker
731*6777b538SAndroid Build Coastguard WorkerIf you encounter a suspicious ASan report, it may be helpful to re-run Chromium
732*6777b538SAndroid Build Coastguard Workerwith an increased quarantine capacity as follows:
733*6777b538SAndroid Build Coastguard Worker
734*6777b538SAndroid Build Coastguard Worker```
735*6777b538SAndroid Build Coastguard WorkerASAN_OPTIONS=quarantine_size_mb=1024 path/to/chrome
736*6777b538SAndroid Build Coastguard Worker```
737*6777b538SAndroid Build Coastguard Worker
738*6777b538SAndroid Build Coastguard Worker## Appendix: Is raw_ptr Live?
739*6777b538SAndroid Build Coastguard Worker
740*6777b538SAndroid Build Coastguard Worker![Diagram showing how both code support and feature flag must be present
741*6777b538SAndroid Build Coastguard Worker  for raw_ptr to be BRP.](./raw_ptr_liveness.png)
742*6777b538SAndroid Build Coastguard Worker
743*6777b538SAndroid Build Coastguard WorkerNote that
744*6777b538SAndroid Build Coastguard Worker
745*6777b538SAndroid Build Coastguard Worker*   [`RawPtrNoOpImpl`][raw-ptr-noop-impl] is thought to have no
746*6777b538SAndroid Build Coastguard Worker    overhead. However, this has yet to be verified.
747*6777b538SAndroid Build Coastguard Worker
748*6777b538SAndroid Build Coastguard Worker*   "Inert BackupRefPtr" _has_ overhead - once BRP support is compiled
749*6777b538SAndroid Build Coastguard Worker    in, every `raw_ptr` will (at assignment) perform the
750*6777b538SAndroid Build Coastguard Worker    check that asks, ["is BRP protection active?"][is-brp-active]
751*6777b538SAndroid Build Coastguard Worker
752*6777b538SAndroid Build Coastguard WorkerAs for general BRP enablement,
753*6777b538SAndroid Build Coastguard Worker
754*6777b538SAndroid Build Coastguard Worker*   BRP is live in most browser tests and Chromium targets.
755*6777b538SAndroid Build Coastguard Worker
756*6777b538SAndroid Build Coastguard Worker    *   This is nuanced by platform type and process type.
757*6777b538SAndroid Build Coastguard Worker
758*6777b538SAndroid Build Coastguard Worker*   In unit tests,
759*6777b538SAndroid Build Coastguard Worker
760*6777b538SAndroid Build Coastguard Worker    *   `raw_ptr` is the no-op impl when the build is ASan.
761*6777b538SAndroid Build Coastguard Worker
762*6777b538SAndroid Build Coastguard Worker    *   `raw_ptr` is live BRP on bots.
763*6777b538SAndroid Build Coastguard Worker
764*6777b538SAndroid Build Coastguard Worker    *   `raw_ptr` is inert BRP otherwise (see https://crbug.com/1440658).
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker[raw-ptr-noop-impl]: https://source.chromium.org/search?q=class:RawPtrNoOpImpl&ss=chromium
767*6777b538SAndroid Build Coastguard Worker[is-brp-active]: https://source.chromium.org/search?q=func:RawPtrBackupRefImpl::IsSupportedAndNotNull&ss=chromium
768