-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Add pointer field protection feature. #133538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/pcc/spr/main.add-pointer-field-protection-feature
Are you sure you want to change the base?
Changes from 1 commit
3bdbe71
40b2f77
0d82cb3
50ab633
5b1e91a
305174e
7dace43
e816ed1
0866b8f
2923a5d
ccf26e0
76a68c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -365,6 +365,17 @@ class LangOptionsBase { | |
BKey | ||
}; | ||
|
||
enum class PointerFieldProtectionKind { | ||
|
||
/// Pointer field protection disabled | ||
None, | ||
/// Pointer field protection enabled, allocator does not tag heap | ||
/// allocations. | ||
Untagged, | ||
/// Pointer field protection enabled, allocator is expected to tag heap | ||
/// allocations. | ||
Tagged, | ||
}; | ||
|
||
enum class ThreadModelKind { | ||
/// POSIX Threads. | ||
POSIX, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -542,6 +542,7 @@ TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, IsPointerInterconvertibleBas | |
|
||
// Clang-only C++ Type Traits | ||
TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX) | ||
TYPE_TRAIT_1(__has_non_relocatable_fields, HasNonRelocatableFields, KEYCXX) | ||
|
||
TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable, KEYCXX) | ||
TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX) | ||
TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2957,6 +2957,12 @@ defm experimental_omit_vtable_rtti : BoolFOption<"experimental-omit-vtable-rtti" | |
NegFlag<SetFalse, [], [CC1Option], "Do not omit">, | ||
BothFlags<[], [CC1Option], " the RTTI component from virtual tables">>; | ||
|
||
def experimental_pointer_field_protection_EQ : Joined<["-"], "fexperimental-pointer-field-protection=">, Group<f_Group>, | ||
|
||
Visibility<[ClangOption, CC1Option]>, | ||
Values<"none,untagged,tagged">, NormalizedValuesScope<"LangOptions::PointerFieldProtectionKind">, | ||
NormalizedValues<["None", "Untagged", "Tagged"]>, | ||
MarshallingInfoEnum<LangOpts<"PointerFieldProtection">, "None">; | ||
|
||
def fcxx_abi_EQ : Joined<["-"], "fc++-abi=">, | ||
Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>, | ||
HelpText<"C++ ABI to use. This will override the target C++ ABI.">; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This an ABI break so I don't think it can reasonably an on by default for all structs - we can already see annotations in libc++, and they would be needed on every single struct field.
We can imagine a new platform where this would be the platform ABI, but for every other case it is functionally unusable.
I would recommend attributes to permit opt in and opt out on a per-struct basis, and CLI flags to select the default behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are numerous circumstances where the C++ ABI is distinct from the platform ABI and is allowed to change. For example, most Chromium-based web browsers ship with a statically linked libc++, and the same is true for many Android apps and server-side software at Google. In the intended usage model, all of libc++ would be built with a
-fexperimental-pointer-field-protection=
flag consistent with the rest of the program.The libc++abi opt-outs that I added are only for opting out pointer fields of RTTI structs that are generated by the compiler. In principle, we could teach the compiler to sign those pointer fields which would let us remove the opt-outs, but there is a lower ROI for subjecting those fields to PFP because the RTTI structs are not typically dynamically allocated.
We may consider adding an attribute to allow opting in in the case where the flag is not passed. But I think we should do that in a followup. We would need to carefully consider how that would interact with the other aspects of the opt-in solution, such as the pointer qualifiers.