-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang][PAC][NFC] Provide addition support macros to ptrauth.h #161027
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: main
Are you sure you want to change the base?
Changes from all commits
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 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -199,6 +199,25 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; | |||||||||
ptrauth_auth_and_resign(__value, __old_key, __old_data, \ | ||||||||||
ptrauth_key_function_pointer, 0) | ||||||||||
|
||||||||||
/* Cast a value to the given type without changing any signature. | ||||||||||
|
||||||||||
The type must be a pointer sized type compatible with the __ptrauth | ||||||||||
qualifier. | ||||||||||
The value must be an expression with a non-address diversified pointer | ||||||||||
authentication schema, and will be converted to an rvalue prior to the cast. | ||||||||||
The result has type given by the first argument. | ||||||||||
Comment on lines
+206
to
+208
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. Probably neither value nor result type can be address-diversified? Or is it possible to request address diversity on the result by some С++ trick? |
||||||||||
|
||||||||||
The result has an identical bit-pattern to the input pointer. */ | ||||||||||
#define ptrauth_nop_cast(__type, __value) \ | ||||||||||
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. It's probably worth adding tests at least for this macro since it's not trivial. Tests for other macros would be nice to have as well. |
||||||||||
({ \ | ||||||||||
union { \ | ||||||||||
typeof(*(__value)) *__fptr; \ | ||||||||||
typeof(__type) __opaque; \ | ||||||||||
} __storage; \ | ||||||||||
__storage.__fptr = (__value); \ | ||||||||||
__storage.__opaque; \ | ||||||||||
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. While this should be valid in C, in C++ reading from the member of the union that wasn't most recently written is technically UB: https://en.cppreference.com/w/cpp/language/union.html. I think we need to conform to C++ standard and use smth like |
||||||||||
}) | ||||||||||
|
||||||||||
/* Authenticate a data pointer. | ||||||||||
|
||||||||||
The value must be an expression of non-function pointer type. | ||||||||||
|
@@ -241,6 +260,18 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; | |||||||||
#define ptrauth_type_discriminator(__type) \ | ||||||||||
__builtin_ptrauth_type_discriminator(__type) | ||||||||||
|
||||||||||
/* Compute the constant discriminator used by Clang to sign pointers with the | ||||||||||
given C function pointer type. | ||||||||||
|
||||||||||
A call to this function is an integer constant expression. */ | ||||||||||
#if __has_feature(ptrauth_function_pointer_type_discrimination) | ||||||||||
#define ptrauth_function_pointer_type_discriminator(__type) \ | ||||||||||
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. Nit: it's very subjective, but I find the naming a bit misleading. When I first read this, I though that this unconditionally defines a discriminator which is dependent on function type, while the discriminator is either type-based or constant zero depending on Maybe we can just avoid the word "type" in macro name, like Feel free to ignore. |
||||||||||
__builtin_ptrauth_type_discriminator(__type) | ||||||||||
#else | ||||||||||
#define ptrauth_function_pointer_type_discriminator(__type) \ | ||||||||||
((ptrauth_extra_data_t)0) | ||||||||||
#endif | ||||||||||
|
||||||||||
/* Compute a signature for the given pair of pointer-sized values. | ||||||||||
The order of the arguments is significant. | ||||||||||
|
||||||||||
|
@@ -263,6 +294,32 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; | |||||||||
#define ptrauth_sign_generic_data(__value, __data) \ | ||||||||||
__builtin_ptrauth_sign_generic_data(__value, __data) | ||||||||||
|
||||||||||
/* Define some standard __ptrauth qualifiers used in the ABI. */ | ||||||||||
#define __ptrauth_function_pointer(__typekey) \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 0, __typekey) | ||||||||||
Comment on lines
+298
to
+299
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
|
||||||||||
#define __ptrauth_return_address __ptrauth(ptrauth_key_return_address, 1, 0) | ||||||||||
#define __ptrauth_block_invocation_pointer \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 1, 0) | ||||||||||
#define __ptrauth_block_copy_helper \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 1, 0) | ||||||||||
#define __ptrauth_block_destroy_helper \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 1, 0) | ||||||||||
#define __ptrauth_block_byref_copy_helper \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 1, 0) | ||||||||||
#define __ptrauth_block_byref_destroy_helper \ | ||||||||||
__ptrauth(ptrauth_key_function_pointer, 1, 0) | ||||||||||
#if __has_feature(ptrauth_signed_block_descriptors) | ||||||||||
#define __ptrauth_block_descriptor_pointer \ | ||||||||||
__ptrauth(ptrauth_key_block_descriptor_pointer, 1, 0xC0BB) | ||||||||||
#else | ||||||||||
#define __ptrauth_block_descriptor_pointer | ||||||||||
#endif | ||||||||||
|
||||||||||
#define __ptrauth_cxx_vtable_pointer \ | ||||||||||
__ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0) | ||||||||||
#define __ptrauth_cxx_vtt_vtable_pointer \ | ||||||||||
__ptrauth(ptrauth_key_cxx_vtable_pointer, 0, 0) | ||||||||||
|
||||||||||
/* C++ vtable pointer signing class attribute */ | ||||||||||
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \ | ||||||||||
extra_discrimination...) \ | ||||||||||
|
@@ -371,7 +428,10 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; | |||||||||
((ptrauth_extra_data_t)0); \ | ||||||||||
}) | ||||||||||
|
||||||||||
#define ptrauth_nop_cast(__type, __value) (__type)(__value) | ||||||||||
#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0) | ||||||||||
#define ptrauth_function_pointer_type_discriminator(__type) \ | ||||||||||
((ptrauth_extra_data_t)0) | ||||||||||
|
||||||||||
#define ptrauth_sign_generic_data(__value, __data) \ | ||||||||||
({ \ | ||||||||||
|
@@ -384,9 +444,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; | |||||||||
#define ptrauth_cxx_vtable_pointer(key, address_discrimination, \ | ||||||||||
extra_discrimination...) | ||||||||||
|
||||||||||
#define __ptrauth_function_pointer(__typekey) | ||||||||||
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. Could you please explain what purpose do these empty macros serve for? 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. @kovdan01 As far as I understand, they are intended to be used along the lines callback_t __ptrauth_function_pointer(ptrauth_function_pointer_type_discriminator(callback_t)) *cb; or as a better example struct state {
// ...
uintptr_t __ptrauth_return_address saved_ret_addr;
// ...
}; You have to "annotate" the variables with such macros at least once anyway, so without these empty defines you would have to duplicate variable definitions under PS: Same as above :)
Suggested change
|
||||||||||
#define __ptrauth_return_address | ||||||||||
#define __ptrauth_block_invocation_pointer | ||||||||||
#define __ptrauth_block_copy_helper | ||||||||||
#define __ptrauth_block_destroy_helper | ||||||||||
#define __ptrauth_block_byref_copy_helper | ||||||||||
#define __ptrauth_block_byref_destroy_helper | ||||||||||
#define __ptrauth_block_descriptor_pointer | ||||||||||
#define __ptrauth_objc_method_list_imp | ||||||||||
#define __ptrauth_objc_method_list_pointer | ||||||||||
#define __ptrauth_objc_isa_pointer | ||||||||||
#define __ptrauth_objc_isa_uintptr | ||||||||||
#define __ptrauth_objc_super_pointer | ||||||||||
#define __ptrauth_cxx_vtable_pointer | ||||||||||
#define __ptrauth_cxx_vtt_vtable_pointer | ||||||||||
#define __ptrauth_objc_sel | ||||||||||
#define __ptrauth_objc_class_ro | ||||||||||
|
||||||||||
#endif /* __has_feature(ptrauth_intrinsics) || defined(__PTRAUTH__) */ | ||||||||||
|
||||||||||
|
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.
It is probably worth clarifying explicitly whether this applies to "input" type (implicitly provided via
__value
), "output" type (explicitly specified by__type
argument) or both.