Urea医学上是什么意思| 富不过三代是什么意思| 枸杞子和什么泡水喝补肾壮阳| 女性什么时候退休| 丙球是什么| 胃胀胃酸是什么原因| 一台什么| b1是什么意思| bc是什么牌子| 软化耳屎的药水叫什么| 的字五行属什么| 胖脸适合什么发型| 子宫后倾位是什么意思| 什么清什么楚| 甲减有什么症状表现| 签证是什么| 牙痛吃什么药最快见效| 脚心发热是什么原因| 保胎是什么意思| 亢是什么意思| 复活节是什么意思| 重庆有什么景点| 双向情感障碍是什么病| 香港是什么时候回归的| 淼念什么| 经期吃凉的东西有什么影响| 早餐吃什么有营养| 手为什么会发麻| 股骨头坏死吃什么药| 中国国花是什么花| 泌尿系彩超主要是检查什么| 梦见好多动物是什么意思| pci是什么| 顶格是什么意思| 忌作灶是什么意思| 化疗后吃什么恢复快| 名列前茅的茅是什么意思| 运动后恶心想吐是什么原因| 熠熠什么意思| 痱子长什么样子图片| miffy是什么意思| 男生留什么发型好看| 属羊的守护神是什么菩萨| 香蕉对身体有什么好处| 破伤风是什么| jk什么意思| 肛瘘是什么情况| 猫睡在枕头旁说明什么| 手掌疼是什么原因| 荠菜什么时候播种最好| 半熟芝士是什么意思| 深耕是什么意思| 似乎是什么意思| 什么叫体位性低血压| 亲戚是什么意思| cav是什么意思| 脸上长痤疮用什么药| 新生儿打嗝是什么原因| o型血和什么血型容易溶血| 警察是什么生肖| b超是查什么的| 5月9日是什么星座| 甲状腺结节吃什么中药| 什么是梅毒| 精神病人最怕什么刺激| 梦见邻居是什么意思| 果冻是什么做的| 猪朋狗友是什么意思| 居居是什么意思| 犯六冲是什么意思| 迅雷不及掩耳之势是什么意思| 车仔面为什么叫车仔面| invent是什么意思| 剑走偏锋是什么意思| 8月29号是什么日子| 什么山色| 一眼万年什么意思| 爱出者爱返福往者福来是什么意思| 为什么会得炎症| 医保卡有什么用| 凉血是什么意思| 烤冷面是什么做的| 江湖是什么| 脑血管痉挛是什么原因引起的| 8月27日什么星座| 女装什么牌子好| 二狗子是什么意思| 酒酿蛋什么时候吃效果最好| 叒怎么读音是什么意思| 魂不守舍什么意思| 连续做噩梦是什么原因| 净字五行属什么| 人性是什么意思| 抗日战争什么时候开始的| 航五行属什么| 流苏是什么意思| 演唱会安可是什么意思| 64属什么| 有什么颜色| 黄疸偏高有什么危害| 端午节安康是什么意思| 肚脐连着什么器官| 71年出生属什么生肖| 戴朱砂有什么好处| 经常爱放屁是什么原因| 兔子的耳朵有什么作用| 灵芝泡水喝有什么功效| 生死劫是什么意思| 焦虑是什么| svc是什么意思| 抽筋吃什么药见效快| 什么的叶丛| 舅舅的儿子叫什么| 病入膏肓什么意思| 艾拉是什么药这么贵| 经常口腔溃疡是什么原因| 4.21什么星座| 蝉蜕是什么| aigner是什么牌子| 抗衰老吃什么| 小学教师需要什么学历| 为什么眼皮会跳| 内分泌科主要看什么| 爱无能是什么意思| 商朝后面是什么朝代| 肚子一直咕咕叫是什么原因| 海马是什么动物| 晚上睡觉容易醒是什么原因| 霉菌感染用什么药最好| 反驳是什么意思| 新生儿拉肚子是什么原因引起的| 右眼皮跳是什么预兆女| 九孔藕和七孔藕有什么区别| copd什么意思| 宫腔积液吃什么药效果最好| 翩翩起舞是什么意思| 什么叫鳞状细胞| 什么是直肠炎| 赤道2什么时候上映| 印度总统叫什么名字| 大腿根部痛是什么原因| 牙疼有什么办法| 乔峰和洪七公什么关系| 万圣节应该送什么礼物| 高血压和高血脂有什么区别| 欧舒丹属于什么档次| 吃什么补维生素b| 肥皂水是什么| cdr是什么意思| 慢性活动性胃炎是什么意思| 肺结节吃什么水果好| 男生喜欢什么| 沙发是什么发质| 梦见床代表什么预兆| 感光度是什么意思| 盆腔炎有什么症状| arg是什么氨基酸| 鹦鹉能吃什么水果| 一个草字头一个氏念什么| 备货是什么意思| 充电宝100wh是什么意思| 爱吃甜食是什么原因| 为什么孩子要跟爸爸姓| 双侧卵巢多囊性改变是什么意思| ibs是什么意思| 鹌鹑蛋是什么动物的蛋| 脾湿热吃什么中成药| 地中海贫血是什么原因引起的| prep是什么药| 中线是什么意思| 活动无耐力与什么有关| 脚底灼热是什么原因| 梦见别人家办丧事是什么意思| 荆州是现在的什么地方| 中秋节送什么好| 蜜蜂为什么会蜇人| 闪婚是什么意思| 噗噗是什么意思| 幽门螺杆菌吃什么药最好| 沸石为什么能防止暴沸| 天气一热身上就痒是什么原因| 阴道口溃疡用什么药| 什么能软化血管| 耳鸣用什么药| 平菇不能和什么一起吃| 什么叫痤疮| 相对湿度是什么意思| 小便是红色的是什么原因男性| 从容不迫什么意思| 炮灰是什么意思| 热锅凉油是什么意思| 梭织棉是什么面料| 喉咙痛是什么原因引起的| 1941属什么生肖| 手脱皮是缺什么维生素| 头皮痛什么原因引起的| 药物制剂是干什么的| 做梦梦到鸡是什么意思| 什么是白血病| 剖腹产坐月子吃什么| 爸爸过生日送什么礼物| 吹空调感冒咳嗽吃什么药| 发烧呕吐吃什么药| 霍山黄芽属于什么茶| 轰20什么时候首飞| 儿童乐园有什么好玩的| 食人鱼的天敌是什么| 外围是什么| 眼珠子发黄是什么原因| 黑色碳素笔是什么| 手突然发痒是什么原因| 哲是什么意思| 香菇不能和什么一起吃| 附子理中丸治什么病| 沙土地适合种什么农作物| 血糖高看什么科室| 养殖什么最赚钱| 去非洲要打什么疫苗| 艾滋病中期有什么症状| 1007是什么星座| 喝鲜羊奶有什么好处和坏处| 大量出汗是什么原因| 骨折吃什么恢复得快| 最大的沙漠是什么| 力五行属什么| vip是什么意思| 雪人是什么生肖| 豆是什么结构| 慢性浅表性胃炎吃什么药好得快| 猫和狗为什么是天敌| 五音是什么| 七九年属什么生肖| 血管脆是什么原因| 皮肤科属于什么科室| 摸不到心跳是什么情况| 晚上睡觉流口水是什么病| 啤酒加鸡蛋有什么功效| 八月一日是什么日子| 荨麻疹抹什么药| 青椒是什么意思| 罴是什么动物| 点痣不能吃什么东西| 手上起倒刺是缺什么| 阴道出血用什么药| ex什么意思| 什么颜色加什么颜色等于棕色| 嘉靖为什么不杀严嵩| 什么是积食| 什么叫四大皆空| 唐氏综合症是什么| 无花果吃多了有什么坏处| 哥弟属于什么档次| 品规是什么意思| 志司是什么意思| 冲煞是什么意思| 头发干燥是什么原因| 榴莲吃起来口感像什么| 过期药品是什么垃圾| 女人的逼是什么意思| 舍本逐末是什么意思| 血糖高可以吃什么| 上火喝什么饮料| 喝啤酒吃什么菜最好| 为什么卧室要用木地板| 百度

福州洋下海绵公园拟6月建成 汛期可蓄水7000m3

Quick rules

百度 同时小涂亦不用承担伤者的医药费用。

Before telling you what raw_ptr<T> is, we'd like you to follow one simple rule: think of it as a raw C++ pointer. In particular:

  • Initialize it yourself, don't assume the constructor default-initializes it (it may or may not). (Always use the raw_ptr<T> member_ = nullptr; form of initialization rather than the so-called uniform initialization form (empty braces) raw_ptr<T> member_{}; whose meaning varies with the implementation.)
  • Don't assume that moving clears the pointer (it may or may not).
  • The owner of the memory must free it when the time is right, don‘t assume raw_ptr<T> will free it for you (it won’t). Unlike std::unique_ptr<T>, base::scoped_refptr<T>, etc., it does not manage ownership or lifetime of an allocated object.
    • if the pointer is the owner of the memory, consider using an alternative smart pointer.
  • Don't assume raw_ptr<T> will protect you from freeing memory too early (it likely will, but there are gotchas; one of them is that dereferencing will result in other type of undefined behavior).

(There are other, much more subtle rules that you should follow, but they're harder to accidentally violate, hence discussed in the further section “Extra pointer rules”.)

What is |raw_ptr<T>|

raw_ptr<T> is a part of the MiraclePtr project and currently implements the BackupRefPtr algorithm. If needed, please reach out to memory-safety-dev@chromium.org or (Google-internal) chrome-memory-safety@google.com with questions or concerns.

raw_ptr<T> is a non-owning smart pointer that has improved memory-safety over raw pointers. It behaves just like a raw pointer on platforms where USE_RAW_PTR_BACKUP_REF_IMPL is off, and almost like one when it's on. The main difference is that when USE_RAW_PTR_BACKUP_REF_IMPL is enabled, raw_ptr<T> is beneficial for security, because it can prevent a significant percentage of Use-after-Free (UaF) bugs from being exploitable. It achieves this by quarantining the freed memory as long as any dangling raw_ptr<T> pointing to it exists, and poisoning it (with 0xEF..EF pattern).

Note that the sheer act of dereferencing a dangling pointer won't crash, but poisoning increases chances that a subsequent usage of read memory will crash (particularly if the read poison is interpreted as a pointer and dereferenced thereafter), thus giving us a chance to investigate and fix. Having said that, we want to emphasize that dereferencing a dangling pointer remains an Undefined Behavior.

raw_ptr<T> protection is enabled by default in all non-Renderer processes, on:

  • Android (incl. AndroidWebView, Android WebEngine, & Android ChromeCast)
  • Windows
  • ChromeOS
  • macOS
  • Linux
  • Fuchsia

In particular, it isn't yet enabled by default on:

  • iOS
  • Linux CastOS (Nest hardware)

For the source of truth, both enable_backup_ref_ptr_support and enable_backup_ref_ptr_feature_flag need to enabled. Please refer to the following files: build_overrides/partition_alloc.gni and partition_alloc.gni

When to use |raw_ptr<T>|

The Chromium C++ Style Guide asks to use raw_ptr<T> for class and struct fields in place of a raw C++ pointer T* whenever possible, except in Renderer-only code. This guide offers more details.

The usage guidelines are currently enforced via Chromium Clang Plugin. We allow exclusions via:

  • RAW_PTR_EXCLUSION C++ attribute to exclude individual fields. Examples:
  • RawPtrManualPathsToIgnore.h to exclude at a directory level (NOTE, use it as last resort, and be aware it'll require a Clang plugin roll). Examples:
    • Renderer-only code (i.e. code in paths that contain /renderer/ or third_party/blink/public/web/)
    • Code that cannot depend on //base
    • Code in //ppapi
  • No explicit exclusions are needed for:
    • const char*, const wchar_t*, etc.
    • Function pointers
    • ObjC pointers

Examples of using |raw_ptr<T>| instead of raw C++ pointers

Consider an example struct that uses raw C++ pointer fields:

struct Example {
  int* int_ptr;
  void* void_ptr;
  SomeClass* object_ptr;
  const SomeClass* ptr_to_const;
  SomeClass* const const_ptr;
};

When using raw_ptr<T> the struct above would look as follows:

#include "base/memory/raw_ptr.h"

struct Example {
  raw_ptr<int> int_ptr;
  raw_ptr<void> void_ptr;
  raw_ptr<SomeClass> object_ptr;
  raw_ptr<const SomeClass> ptr_to_const;
  const raw_ptr<SomeClass> const_ptr;
};

In most cases, only the type in the field declaration needs to change. In particular, raw_ptr<T> implements operator->, operator* and other operators that one expects from a raw pointer. Cases where other code needs to be modified are described in the “Recoverable compile-time problems” section below.

Performance

Performance impact of using |raw_ptr<T>| instead of |T*|

Compared to a raw C++ pointer, on platforms where USE_RAW_PTR_BACKUP_REF_IMPL is on, raw_ptr<T> incurs additional runtime overhead for initialization, destruction, and assignment (including ptr++, ptr += ..., etc.). There is no overhead when dereferencing or extracting a pointer (including *ptr, ptr->foobar, ptr.get(), or implicit conversions to a raw C++ pointer). Finally, raw_ptr<T> has exactly the same memory footprint as T* (i.e. sizeof(raw_ptr<T>) == sizeof(T*)).

One source of the performance overhead is a check whether a pointer T* points to a protected memory pool. This happens in raw_ptr<T>'s constructor, destructor, and assignment operators. If the pointed memory is unprotected, then raw_ptr<T> behaves just like a T* and the runtime overhead is limited to that extra check. (The security protection incurs additional overhead described in the “Performance impact of enabling Use-after-Free protection” section below.)

Some additional overhead comes from setting raw_ptr<T> to nullptr when default-constructed, destructed, or moved. (Yes, we said above to not rely on it, but to be precise this will always happen when USE_RAW_PTR_BACKUP_REF_IMPL is on; no guarantees otherwise.)

During the “Big Rewrite” most Chromium T* fields have been rewritten to raw_ptr<T> (excluding fields in Renderer-only code). The cumulative performance impact of such rewrite has been measured by earlier A/B binary experiments. There was no measurable impact, except that 32-bit platforms have seen a slight increase in jankiness metrics (for more detailed results see the document here).

Performance impact of enabling Use-after-Free protection

When the Use-after-Free protection is enabled, then raw_ptr<T> has some additional performance overhead.

The protection can increase memory usage:

  • For each memory allocation Chromium‘s allocator (PartitionAlloc) carves out extra 4 bytes. (That doesn’t necessarily mean that each allocation grows by 4B. Allocation sizes come from predefined buckets, so it's possible for an allocation to stay within the same bucket and incur no additional overhead, or hop over to the next bucket and incur much higher overhead.)
  • Freed memory is quarantined and not available for reuse as long as dangling raw_ptr<T> pointers exist. (In practice this overhead has been observed to be low, but on a couple occasions it led to significant memory leaks, fortunately caught early.)

The protection increases runtime costs - raw_ptr<T>‘s constructor, destructor, and assignment operators need to maintain BackupRefPtr’s ref-count (atomic increment/decrement). ptr++, ptr += ..., etc. don't need to do that, but instead have to incur the cost of verifying that resulting pointer stays within the same allocation (important for BRP integrity).

When it is okay to continue using raw C++ pointers

Unsupported cases leading to compile errors

Continue to use raw C++ pointers in the following cases, which may otherwise result in compile errors:

  • Function pointers
  • Pointers to Objective-C objects
  • Pointer fields in classes/structs that are used as global, static, or thread_local variables (see more details in the Rewrite exclusion statistics )
  • Pointers in unions, as well as pointer fields in classes/structs that are used in unions (side note, std::variant is strongly preferred)
  • Code that doesn’t depend on //base (including non-Chromium repositories and third party libraries)
  • Code in //ppapi

Pointers to unprotected memory (performance optimization)

Using raw_ptr<T> offers no security benefits (no UaF protection) for pointers that don’t point to protected memory (only PartitionAlloc-managed heap allocations in non-Renderer processes are protected). Therefore in the following cases raw C++ pointers may be used instead of raw_ptr<T>:

  • Pointer fields that can only point outside PartitionAlloc, including literals, stack allocated memory, shared memory, mmap'ed memory, V8/Oilpan/Java heaps, TLS, etc.
  • const char* (and const wchar_t*) pointer fields, unless you’re convinced they can point to a heap-allocated object, not just a string literal
  • Pointer fields in certain renderer code. Specifically, we disallow usage in
third_party/blink/renderer/core/
third_party/blink/renderer/platform/heap/
third_party/blink/renderer/platform/wtf/

Other perf optimizations

As a performance optimization, raw C++ pointers may be used instead of raw_ptr<T> if it would have a significant performance impact.

Pointers in locations other than fields

Use raw C++ pointers instead of raw_ptr<T> in the following scenarios:

  • Pointers in local variables and function parameters and return values. This includes pointer fields in classes/structs that are used only on the stack. (Using raw_ptr<T> here would cumulatively lead to performance regression and the security benefit of UaF protection is lower for such short-lived pointers.)
  • Pointer fields in unions. However, note that a much better, modern alternative is std::variant + raw_ptr<T>. If use of C++ union is absolutely unavoidable, prefer a regular C++ pointer: incorrect management of a raw_ptr<T> field can easily lead to ref-count corruption.
  • Pointers whose addresses are used only as identifiers and which are never dereferenced (e.g. keys in a map). There is a performance gain by not using raw_ptr in this case; prefer to use uintptr_t to emphasize that the entity can dangle and must not be dereferenced. (NOTE, this is a dangerous practice irrespective of raw_ptr usage, as there is a risk of memory being freed and another pointer allocated with the same address!)

You don’t have to, but may use raw_ptr<T>, in the following scenarios:

  • Pointers that are used as an element type of collections/wrappers. E.g. std::vector<T*> and std::vector<raw_ptr<T>> are both okay, but prefer the latter if the collection is a class field (note that some of the perf optimizations above might still apply and argue for using a raw C++ pointer).

Signal Handlers

raw_ptr<T> assumes that the allocator's data structures are in a consistent state. Signal handlers can interrupt in the middle of an allocation operation; therefore, raw_ptr<T> should not be used in signal handlers.

Extra pointer rules

raw_ptr<T> requires following some extra rules compared to a raw C++ pointer:

  • Don’t assign invalid, non-null addresses (this includes previously valid and now freed memory, Win32 handles, and more). You can only assign an address of memory that is valid at the time of assignment. Exceptions:
    • a pointer to the end of a valid allocation (but not even 1 byte further)
    • a pointer to the last page of the address space, e.g. for sentinels like reinterpret_cast<void*>(-1)
  • Don’t initialize or assign raw_ptr<T> memory directly (e.g. reinterpret_cast<ClassWithRawPtr*>(buffer) or memcpy(reinterpret_cast<void*>(&obj_with_raw_ptr), buffer).
  • Don’t assign to a raw_ptr<T> concurrently, even if the same value.
  • Don’t rely on moved-from pointers to keep their old value. Unlike raw pointers, raw_ptr<T> may be cleared upon moving.
  • Don't use the pointer after it is destructed. Unlike raw pointers, raw_ptr<T> may be cleared upon destruction. This may happen e.g. when fields are ordered such that the pointer field is destructed before the class field whose destructor uses that pointer field (e.g. see Esoteric Issues).
  • Don’t assign to a raw_ptr<T> until its constructor has run. This may happen when a base class’s constructor uses a not-yet-initialized field of a derived class (e.g. see Applying MiraclePtr).

Some of these would result in undefined behavior (UB) even in the world without raw_ptr<T> (e.g. see Field destruction order), but you’d likely get away without any consequences. In the raw_ptr<T> world, an obscure crash may occur. Those crashes often manifest themselves as SEGV or CHECK inside RawPtrBackupRefImpl::AcquireInternal() or RawPtrBackupRefImpl::ReleaseInternal(), but you may also experience memory corruption or a silent drop of UaF protection.

Pointer Annotations

The AllowPtrArithmetic trait

In an ideal world, a raw_ptr would point to a single object, rather than to a C-style array of objects accessed via pointer arithmetic, since the latter is best handled via a C++ construct such as base::span<> or std::vector<>. raw_ptrs upon which such operations are performed and for which conversion is desirable have been tagged with the AllowPtrArithmetic trait. That all such pointer are tagged can be enforced by setting the GN build arg enable_pointer_arithmetic_trait_check=true.

The AllowUninitialized trait

When building Chromium, raw_ptrs are always nullptr initialized, either as the result of specific implementation that requires it (e.g. BackupRefPtr), or as the result of build flags (to enforce consistency). However, we provide an opt-out to allow third-party code to skip this step (where possible). Use this trait sparingly.

Recoverable compile-time problems

Explicit |raw_ptr.get()| might be needed

If a raw pointer is needed, but an implicit cast from raw_ptr<SomeClass> to SomeClass* doesn't work, then the raw pointer needs to be obtained by explicitly calling .get(). Examples:

  • auto* raw_ptr_var = wrapped_ptr_.get() (auto* requires the initializer to be a raw pointer)
    • Alternatively you can change auto* to auto&. Avoid using auto as it’ll copy the pointer, which incurs a performance overhead.
  • return condition ? raw_ptr : wrapped_ptr_.get(); (ternary operator needs identical types in both branches)
  • TemplatedFunction(wrapped_ptr_.get()); (implicit cast doesn't kick in for T* arguments in templates)
  • printf("%p", wrapped_ptr_.get()); (can't pass class type arguments to variadic functions)
  • reinterpret_cast<SomeClass*>(wrapped_ptr_.get()) (const_cast and reinterpret_cast sometimes require their argument to be a raw pointer; static_cast should “Just Work”)
  • T2 t2 = t1_wrapped_ptr_.get(); (where there is an implicit conversion constructor T2(T1*) the compiler can handle one implicit conversion, but not two)
  • In general, when type is inferred by a compiler and then used in a context where a pointer is expected.

Out-of-line constructor/destructor might be needed

Out-of-line constructor/destructor may be newly required by the chromium style clang plugin. Error examples:

  • error: [chromium-style] Complex class/struct needs an explicit out-of-line destructor.
  • error: [chromium-style] Complex class/struct needs an explicit out-of-line constructor.

raw_ptr<T> uses a non-trivial constructor/destructor, so classes that used to be POD or have a trivial destructor may require an out-of-line constructor/destructor to satisfy the chromium style clang plugin.

In-out arguments need to be refactored

Due to implementation difficulties, raw_ptr<T> doesn't support an address-of operator. This means that the following code will not compile:

void GetSomeClassPtr(SomeClass** out_arg) {
  *out_arg = ...;
}

struct MyStruct {
  void Example() {
    GetSomeClassPtr(&wrapped_ptr_);  // <- won't compile
  }

  raw_ptr<SomeClass> wrapped_ptr_;
};

The typical fix is to change the type of the out argument (see also an example CL here):

void GetSomeClassPtr(raw_ptr<SomeClass>* out_arg) {
  *out_arg = ...;
}

Similarly this code:

void FillPtr(SomeClass*& out_arg) {
  out_arg = ...;
}

would have to be changed to this:

void FillPtr(raw_ptr<SomeClass>& out_arg) {
  out_arg = ...;
}

Similarly this code:

SomeClass*& GetPtr() {
  return wrapper_ptr_;
}

would have to be changed to this:

raw_ptr<SomeClass>& GetPtr() {
  return wrapper_ptr_;
}

In case you cannot refactor the in-out arguments (e.g. third party library), you may use raw_ptr.AsEphemeralRawAddr() to obtain extremely short-lived T** or T*&. You should not treat T** obtained via raw_ptr.AsEphemeralRawAddr() as a normal pointer pointer, and must follow these requirements.

  • Do NOT store T** or T*& anywhere, even as a local variable.
    • It will become invalid very quickly and can cause dangling pointer issue
  • Do NOT use raw_ptr<T>, T** or T*& multiple times within an expression.
    • The implementation assumes raw_ptr is never accessed when T** or T*& is alive.
void GetSomeClassPtr(SomeClass** out_arg) {
  *out_arg = ...;
}
void FillPtr(SomeClass*& out_arg) {
  out_arg = ...;
}
void Foo() {
  raw_ptr<SomeClass> ptr;
  GetSomeClassPtr(&ptr.AsEphemeralRawAddr());
  FillPtr(ptr.AsEphemeralRawAddr()); // Implicitly converted into |SomeClass*&|.
}

Technically, raw_ptr.AsEphemeralRawAddr() generates a temporary instance of raw_ptr<T>::EphemeralRawAddr, which holds a temporary copy of T*. T** and T*& points to a copied version of the original pointer and any modification made via T** or T*& is written back on destruction of EphemeralRawAddr instance. C++ guarantees a temporary object returned by raw_ptr.AsEphemeralRawAddr() lives until completion of evaluation of “full-expression” (i.e. the outermost expression). This makes it possible to use T** and T*& within single expression like in-out param.

struct EphemeralRawAddr {
  EphemeralRawAddr(raw_ptr& ptr): copy(ptr.get()), original(ptr) {}
  ~EphemeralRawAddr() {
    original = copy;
    copy = nullptr;
  }

  T** operator&() { return &copy; }
  operator T*&() { return copy; }

  T* copy;
  raw_ptr& original;  // Original pointer.
};

Modern |nullptr| is required

As recommended by the Google C++ Style Guide, use nullptr instead of NULL - the latter might result in compile-time errors when used with raw_ptr<T>.

Example:

struct SomeStruct {
  raw_ptr<int> ptr_field;
};

void bar() {
  SomeStruct some_struct;
  some_struct.ptr_field = NULL;
}

Error:

../../base/memory/checked_ptr_unittest.cc:139:25: error: use of overloaded
operator '=' is ambiguous (with operand types raw_ptr<int>' and 'long')
  some_struct.ptr_field = NULL;
  ~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
../../base/memory/raw_ptr.h:369:29: note: candidate function
  ALWAYS_INLINE raw_ptr& operator=(std::nullptr_t) noexcept {
                         ^
../../base/memory/raw_ptr.h:374:29: note: candidate function
  ALWAYS_INLINE raw_ptr& operator=(T* p)
                         noexcept {

[rare] Explicit overload or template specialization for |raw_ptr<T>|

In rare cases, the default template code won’t compile when raw_ptr<...> is substituted for a template argument. In such cases, it might be necessary to provide an explicit overload or template specialization for raw_ptr<T>.

Example (more details in Applying MiraclePtr and the Add CheckedPtr support for cbor_extract::Element CL):

// An explicit overload (taking raw_ptr<T> as an argument)
// was needed below:
template <typename S>
constexpr StepOrByte<S> Element(
    const Is required,
    raw_ptr<const std::string> S::*member,  // <- HERE
    uintptr_t offset) {
  return ElementImpl<S>(required, offset, internal::Type::kString);
}

AddressSanitizer support

For years, AddressSanitizer has been the main tool for diagnosing memory corruption issues in Chromium. MiraclePtr alters the security properties of some of some such issues, so ideally it should be integrated with ASan. That way an engineer would be able to check whether a given use-after-free vulnerability is covered by the protection without having to switch between ASan and non-ASan builds.

Unfortunately, MiraclePtr relies heavily on PartitionAlloc, and ASan needs its own allocator to work. As a result, the default implementation of raw_ptr<T> can't be used with ASan builds. Instead, a special version of raw_ptr<T> has been implemented, which is based on the ASan quarantine and acts as a sufficiently close approximation for diagnostic purposes. At crash time, the tool will tell the user if the dangling pointer access would have been protected by MiraclePtr in a regular build.

You can configure the diagnostic tool by modifying the parameters of the feature flag PartitionAllocBackupRefPtr. For example, launching Chromium as follows:

path/to/chrome --enable-features=PartitionAllocBackupRefPtr:enabled-processes/browser-only/asan-enable-dereference-check/true/asan-enable-extraction-check/true/asan-enable-instantiation-check/true

activates all available checks in the browser process.

Available checks

MiraclePtr provides ASan users with three kinds of security checks, which differ in when a particular check occurs:

Dereference

This is the basic check type that helps diagnose regular heap-use-after-free bugs. It's enabled by default.

Extraction

The user will be warned if a dangling pointer is extracted from a raw_ptr<T> variable. If the pointer is then dereferenced, an ASan error report will follow. In some cases, extra work on the reproduction case is required to reach the faulty memory access. However, even without memory corruption, relying on the value of a dangling pointer may lead to problems. For example, it's a common (anti-)pattern in Chromium to use a raw pointer as a key in a container. Consider the following example:

std::map<T*, std::unique_ptr<Ext>> g_map;

struct A {
  A() {
    g_map[this] = std::make_unique<Ext>(this);
  }

  ~A() {
    g_map.erase(this);
  }
};

raw_ptr<A> dangling = new A;
// ...
delete dangling.get();
A* replacement = new A;
// ...
auto it = g_map.find(dangling);
if (it == g_map.end())
  return 0;
it->second.DoStuff();

Depending on whether the allocator reuses the same memory region for the second A object, the program may inadvertently call DoStuff() on the wrong Ext instance. This, in turn, may corrupt the state of the program or bypass security controls if the two A objects belong to different security contexts.

Given the proportion of false positives reported in the mode, it is disabled by default. It's mainly intended to be used by security researchers who are willing to spend a significant amount of time investigating these early warnings.

Instantiation

This check detects violations of the rule that when instantiating a raw_ptr<T> from a T* , it is only allowed if the T* is a valid (i.e. not dangling) pointer. This rule exists to help avoid an issue called “pointer laundering” which can result in unsafe raw_ptr<T> instances that point to memory that is no longer in quarantine. This is important, since subsequent use of these raw_ptr<T> might appear to be safe.

In order for “pointer laundering” to occur, we need (1) a dangling T* (pointing to memory that has been freed) to be assigned to a raw_ptr<T>, while (2) there is no other raw_ptr<T> pointing to the same object/allocation at the time of assignment.

The check only detects (1), a dangling T* being assigned to a raw_ptr<T>, so in order to determine whether “pointer laundering” has occurred, we need to determine whether (2) could plausibly occur, not just in the specific reproduction testcase, but in the more general case.

In the absence of thorough reasoning about (2), the assumption here should be that any failure of this check is a security issue of the same severity as an unprotected use-after-free.

Protection status

When ASan generates a heap-use-after-free report, it will include a new section near the bottom, which starts with the line MiraclePtr Status: <status>. At the moment, it has three possible options:

Protected

The system is sufficiently confident that MiraclePtr makes the discovered issue unexploitable. In the future, the security severity of such bugs will be reduced.

Manual analysis required

Dangling pointer extraction was detected before the crash, but there might be extra code between the extraction and dereference. Most of the time, the code in question will look similar to the following:

struct A {
  raw_ptr<T> dangling_;
};

void trigger(A* a) {
  // ...
  T* local = a->dangling_;
  DoStuff();
  local->DoOtherStuff();
  // ...
}

In this scenario, even though dangling_ points to freed memory, that memory is protected and will stay in quarantine until dangling_ (and all other raw_ptr<T> variables pointing to the same region) changes its value or gets destroyed. Therefore, the expression a_->dangling->DoOtherStuff() wouldn't trigger an exploitable use-after-free.

You will need to make sure that DoStuff() is sufficiently trivial and can‘t (not only for the particular reproduction case, but even in principle) make dangling_ change its value or get destroyed. If that’s the case, the DoOtherStuff() call may be considered protected. The tool will provide you with the stack trace for both the extraction and dereference events.

Not protected

The dangling T* doesn‘t appear to originate from a raw_ptr<T> variable, which means MiraclePtr can’t prevent this issue from being exploited. In practice, there may still be a raw_ptr<T> in a different part of the code that protects the same allocation indirectly, but such protection won't be considered robust enough to impact security-related decisions.

Limitations

The main limitation of MiraclePtr in ASan builds is the main limitation of ASan itself: the capacity of the quarantine is limited. Eventually, every allocation in quarantine will get reused regardless of whether there are still references to it.

In the context of MiraclePtr combined with ASan, it's a problem when:

  1. A heap allocation that isn't supported by MiraclePtr is made. At the moment, the only such class is allocations made early during the process startup before MiraclePtr can be activated.
  2. Its address is assigned to a raw_ptr<T> variable.
  3. The allocation gets freed.
  4. A new allocation is made in the same memory region as the first one, but this time it is supported.
  5. The second allocation gets freed.
  6. The raw_ptr<T> variable is accessed.

In this case, MiraclePtr will incorrectly assume the memory access is protected. Luckily, considering the small number of unprotected allocations in Chromium, the size of the quarantine, and the fact that most reproduction cases take relatively short time to run, the odds of this happening are very low.

The problem is relatively easy to spot if you look at the ASan report: the allocation and deallocation stack traces won‘t be consistent across runs and the allocation type won’t match the use stack trace.

If you encounter a suspicious ASan report, it may be helpful to re-run Chromium with an increased quarantine capacity as follows:

ASAN_OPTIONS=quarantine_size_mb=1024 path/to/chrome

Appendix: Is raw_ptr Live?

Diagram showing how both code support and feature flag must be presentfor raw_ptr to be BRP.

Note that

  • RawPtrNoOpImpl is thought to have no overhead. However, this has yet to be verified.

  • “Inert BackupRefPtr” has overhead - once BRP support is compiled in, every raw_ptr will (at assignment) perform the check that asks, “is BRP protection active?”

As for general BRP enablement,

  • BRP is live in most browser tests and Chromium targets.

    • This is nuanced by platform type and process type.
  • In unit tests,

市斤是什么意思 什么药治灰指甲最有效 依稀是什么意思 睾丸小是什么原因 生吃大蒜有什么好处和坏处
张菲和费玉清什么关系 两性关系是什么意思 重庆有什么区 白带发绿是什么原因 辅酶q10什么时间吃好
犄角旮旯是什么意思 舌炎吃什么药效果最好 四月二十五是什么星座 十月三十号什么星座 天德是什么意思
腿抖是什么病的预兆 含羞草长什么样 什么是灰指甲 备孕挂什么科 1995年属猪的是什么命
肺大泡吃什么药hcv9jop1ns9r.cn 下巴长痘痘是什么原因引起的hcv7jop5ns5r.cn zw是什么意思hcv8jop5ns0r.cn 淡奶油能做什么luyiluode.com 微信转账为什么要验证码hcv8jop6ns1r.cn
女人脸黄是什么原因该怎么调理hcv8jop4ns9r.cn positive是什么意思hcv9jop6ns1r.cn 蚂蚁吃什么食物hcv8jop3ns5r.cn 急性肠胃炎能吃什么hcv8jop3ns6r.cn 糖尿病可以吃什么肉hcv7jop5ns0r.cn
农历三月三是什么日子hcv9jop0ns4r.cn 查血压高挂什么科室hcv9jop7ns3r.cn 急性中耳炎吃什么药hcv8jop6ns5r.cn 9527是什么梗hcv9jop2ns9r.cn 尿胆红素阳性是什么意思96micro.com
星期天左眼皮跳是什么预兆cj623037.com 左心室强光点是什么意思hcv9jop4ns1r.cn 10.28是什么星座hcv8jop3ns6r.cn 什么药治鼻炎xinjiangjialails.com 眼底出血有什么症状hcv8jop5ns6r.cn
百度