-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Prepare libcxx and libcxxabi for pointer field protection. #151651
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.prepare-libcxx-and-libcxxabi-for-pointer-field-protection
Are you sure you want to change the base?
Changes from 6 commits
1d63bc5
f0e1b0a
13e4502
d8b6925
4f82ef8
a7305bc
7820ec4
d215060
94d9f30
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 |
|---|---|---|
|
|
@@ -484,8 +484,21 @@ typedef __char32_t char32_t; | |
| # define _LIBCPP_EXCEPTIONS_SIG e | ||
| # endif | ||
|
|
||
| # if !_LIBCPP_HAS_EXCEPTIONS | ||
| # define _LIBCPP_EXCEPTIONS_SIG n | ||
| # else | ||
| # define _LIBCPP_EXCEPTIONS_SIG e | ||
| # endif | ||
|
|
||
| # if defined(__POINTER_FIELD_PROTECTION__) | ||
| # define _LIBCPP_PFP_SIG p | ||
| # else | ||
| # define _LIBCPP_PFP_SIG | ||
| # endif | ||
|
|
||
| # define _LIBCPP_ODR_SIGNATURE \ | ||
| _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION) | ||
| _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_PFP_SIG), \ | ||
| _LIBCPP_VERSION) | ||
|
|
||
| // This macro marks a symbol as being hidden from libc++'s ABI. This is achieved | ||
| // on two levels: | ||
|
|
@@ -1263,6 +1276,12 @@ typedef __char32_t char32_t; | |
| # define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER 0 | ||
| # endif | ||
|
|
||
| # if __has_cpp_attribute(_Clang::__no_field_protection__) | ||
| # define _LIBCPP_NO_PFP [[_Clang::__no_field_protection__]] | ||
| # else | ||
| # define _LIBCPP_NO_PFP | ||
| # endif | ||
|
Comment on lines
+1070
to
+1074
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do |
||
|
|
||
| #endif // __cplusplus | ||
|
|
||
| #endif // _LIBCPP___CONFIG | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -34,10 +34,13 @@ template <class _Tp, class = void> | |||||
| struct __libcpp_is_trivially_relocatable : is_trivially_copyable<_Tp> {}; | ||||||
| #endif | ||||||
|
|
||||||
| // __trivially_relocatable on libc++'s builtin types does not currently return the right answer with PFP. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
What do you mean by "libc++ builtin types"? Do you mean libc++ types like
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked at all the types and I think they would all be non-trivially-relocatable with PFP because they can all contain pointer fields. We could surround each
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like what really makes the most sense is to disable it on a per type basis. But perhaps we can extract the fundamental property that makes these types non-TR with PFP into something general in a way that doesn't require an explicit So I guess my question is: what is the fundamental property that makes these types non-TR when PFP is enabled? |
||||||
| #if !defined(__POINTER_FIELD_PROTECTION__) | ||||||
| template <class _Tp> | ||||||
| struct __libcpp_is_trivially_relocatable<_Tp, | ||||||
| __enable_if_t<is_same<_Tp, typename _Tp::__trivially_relocatable>::value> > | ||||||
| : true_type {}; | ||||||
| #endif | ||||||
|
|
||||||
| _LIBCPP_END_NAMESPACE_STD | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -300,7 +300,7 @@ class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info | |
| protected: | ||
| typedef __type_info_implementations::__impl __impl; | ||
|
|
||
| __impl::__type_name_t __type_name; | ||
| _LIBCPP_NO_PFP __impl::__type_name_t __type_name; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To reiterate my comment on the RFC, I would much rather we teach Clang how to generate the right thing here. I understand this might reduce the amount of work needed in Clang, but at the end of the day the PFP implementation in Clang will be more complete and more robust if it can handle this out of the box -- even if the actual security benefits are marginal. The same comment holds for the changes in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would have the following downsides:
That being said, I don't feel strongly about it, so if it doesn't take too much time I guess I don't mind doing it.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Whether there is a "real benefit" is subjective, though. Not having to think about PFP in libc++abi is a very real (and valuable) benefit from my perspective (but perhaps not from someone else's perspective).
Can you explain why that's the case? Where/why is the name of the field relevant when PFP is enabled? That's probably obvious when you know PFP but I'm not seeing it.
IIUC, you are implying that right now, we could link both a PFP libc++ and a non-PFP libc++ into the same program without issues because they use a different inline namespace, and
Let's finish this discussion first! |
||
|
|
||
| _LIBCPP_HIDE_FROM_ABI explicit type_info(const char* __n) : __type_name(__impl::__string_to_type_name(__n)) {} | ||
|
|
||
|
|
||
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.
My understanding is that pfp changes the layout of certain types? Why should there be an ABI tag for it?
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.
Yes, the in-memory pointer format changes so it's effectively a layout (ABI) change. Therefore we need an ABI tag change to detect/prevent linking against mismatching ABIs. This was requested by @mordante in #133538.
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.
That's only for ceses where we want different TUs to link together. Since PFP changes the layout of types that's not something we want users to do, which in turn means that we don't want to make it visible in the ABI tag. We should instead change the whole inline namespace.
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.
Okay, I removed this logic and added CMake logic to modify the namespace name if PFP is enabled.