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<T>| 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<T>| 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<T>| 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<T>| 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 © } 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<T>| 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 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