From 6bc540043d4c3fed8f44c8f6de86be0d1740582e Mon Sep 17 00:00:00 2001 From: Oliver Hunt Date: Sat, 27 Sep 2025 16:22:35 -0700 Subject: [PATCH] [clang][PAC][NFC] Provide addition support macros to ptrauth.h This introduces a number of additional macros to support the use of manual pointer authentication. --- clang/docs/PointerAuthentication.rst | 34 +++++++++++++ clang/lib/Headers/ptrauth.h | 74 ++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst index 96eb498bc48b6..eb4eaf08b854e 100644 --- a/clang/docs/PointerAuthentication.rst +++ b/clang/docs/PointerAuthentication.rst @@ -722,6 +722,40 @@ type. Implementations are not required to make all bits of the result equally significant; in particular, some implementations are known to not leave meaningful data in the low bits. +``ptrauth_nop_cast`` +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_nop_cast(__type, __value) + +Cast a pointer to the given type without changing any signature. + +This operation can be used to convert a value from one type to another without +attempting to re-sign the value. This makes it possible to view a signed value +of one type as another type signed with the same schema. This can be used to +convert implicit schemas to explicit schemas, to convert to or from opaque +types, or simply to change the effective underlying type of a signed value. + +The `__type` must be a pointer sized value compatible with the `__ptrauth` +qualifier. The authentication schema must not include address diversity. + +The result is a bitwise identical value with the type passed as the `__type` +argument. + +``ptrauth_function_pointer_type_discriminator`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + ptrauth_function_pointer_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. + + Standard ``__ptrauth`` qualifiers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index f902ca1e3bbd3..ca9ac5a55ea7d 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -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. + + The result has an identical bit-pattern to the input pointer. */ +#define ptrauth_nop_cast(__type, __value) \ + ({ \ + union { \ + typeof(*(__value)) *__fptr; \ + typeof(__type) __opaque; \ + } __storage; \ + __storage.__fptr = (__value); \ + __storage.__opaque; \ + }) + /* 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) \ + __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) +#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) +#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__) */