diff options
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h | 2 | ||||
-rw-r--r-- | libcxxabi/src/cxa_exception.h | 20 | ||||
-rw-r--r-- | libcxxabi/src/cxa_personality.cpp | 15 | ||||
-rw-r--r-- | libunwind/include/libunwind.h | 4 | ||||
-rw-r--r-- | libunwind/src/CompactUnwinder.hpp | 10 | ||||
-rw-r--r-- | libunwind/src/DwarfInstructions.hpp | 16 | ||||
-rw-r--r-- | libunwind/src/DwarfParser.hpp | 6 |
7 files changed, 41 insertions, 32 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h b/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h index 8c3c063..265a992 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_ptrauth.h @@ -9,7 +9,7 @@ #ifndef SANITIZER_PTRAUTH_H #define SANITIZER_PTRAUTH_H -#if __has_feature(ptrauth_calls) +#if __has_feature(ptrauth_intrinsics) # include <ptrauth.h> #elif defined(__ARM_FEATURE_PAC_DEFAULT) && !defined(__APPLE__) // On the stack the link register is protected with Pointer diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h index aa8969e..1c84f75 100644 --- a/libcxxabi/src/cxa_exception.h +++ b/libcxxabi/src/cxa_exception.h @@ -47,7 +47,7 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { // In Wasm, a destructor returns its argument void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); #else - void(_LIBCXXABI_DTOR_FUNC* __ptrauth_cxxabi_exception_destructor exceptionDestructor)(void*); + void(_LIBCXXABI_DTOR_FUNC *__ptrauth_cxxabi_exception_destructor exceptionDestructor)(void*); #endif std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler; std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler; @@ -61,10 +61,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { int propagationCount; #else int handlerSwitchValue; - const unsigned char* __ptrauth_cxxabi_action_record actionRecord; - const unsigned char* __ptrauth_cxxabi_lsd languageSpecificData; - void* __ptrauth_cxxabi_catch_temp catchTemp; - void* __ptrauth_cxxabi_adjusted_ptr adjustedPtr; + const unsigned char *__ptrauth_cxxabi_action_record actionRecord; + const unsigned char *__ptrauth_cxxabi_lsd languageSpecificData; + void *__ptrauth_cxxabi_catch_temp catchTemp; + void *__ptrauth_cxxabi_adjusted_ptr adjustedPtr; #endif #if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI) @@ -88,7 +88,7 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { #endif std::type_info *exceptionType; - void(_LIBCXXABI_DTOR_FUNC* __ptrauth_cxxabi_exception_destructor exceptionDestructor)(void*); + void(_LIBCXXABI_DTOR_FUNC *__ptrauth_cxxabi_exception_destructor exceptionDestructor)(void*); std::unexpected_handler __ptrauth_cxxabi_unexpected_handler unexpectedHandler; std::terminate_handler __ptrauth_cxxabi_terminate_handler terminateHandler; @@ -102,10 +102,10 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { #else int handlerSwitchValue; - const unsigned char* __ptrauth_cxxabi_action_record actionRecord; - const unsigned char* __ptrauth_cxxabi_lsd languageSpecificData; - void* __ptrauth_cxxabi_catch_temp catchTemp; - void* __ptrauth_cxxabi_adjusted_ptr adjustedPtr; + const unsigned char *__ptrauth_cxxabi_action_record actionRecord; + const unsigned char *__ptrauth_cxxabi_lsd languageSpecificData; + void *__ptrauth_cxxabi_catch_temp catchTemp; + void *__ptrauth_cxxabi_adjusted_ptr adjustedPtr; #endif #if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI) diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index 81ad3a0..4d2c13a 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -564,10 +564,10 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception) namespace { -typedef const uint8_t* __ptrauth_scan_results_lsd lsd_ptr_t; -typedef const uint8_t* __ptrauth_scan_results_action_record action_ptr_t; +typedef const uint8_t *__ptrauth_scan_results_lsd lsd_ptr_t; +typedef const uint8_t *__ptrauth_scan_results_action_record action_ptr_t; typedef uintptr_t __ptrauth_scan_results_landingpad_intptr landing_pad_t; -typedef void* __ptrauth_scan_results_landingpad landing_pad_ptr_t; +typedef void *__ptrauth_scan_results_landingpad landing_pad_ptr_t; struct scan_results { @@ -585,12 +585,16 @@ struct scan_results } // unnamed namespace } // extern "C" +#if !defined(_LIBCXXABI_ARM_EHABI) namespace { // The logical model for casting authenticated function pointers makes // it impossible to directly cast them without breaking the authentication, // as a result we need this pair of helpers. +// +// __ptrauth_nop_cast cannot be used here as the authentication schemas include +// address diversification. template <typename PtrType> -[[maybe_unused]] void set_landing_pad_as_ptr(scan_results& results, const PtrType& out) { +void set_landing_pad_as_ptr(scan_results& results, const PtrType& out) { union { landing_pad_t* as_landing_pad; landing_pad_ptr_t* as_pointer; @@ -599,7 +603,7 @@ template <typename PtrType> *u.as_pointer = out; } -[[maybe_unused]] static const landing_pad_ptr_t& get_landing_pad_as_ptr(const scan_results& results) { +static const landing_pad_ptr_t& get_landing_pad_as_ptr(const scan_results& results) { union { const landing_pad_t* as_landing_pad; const landing_pad_ptr_t* as_pointer; @@ -608,6 +612,7 @@ template <typename PtrType> return *u.as_pointer; } } // unnamed namespace +#endif extern "C" { static diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h index 8798248..5d5b583 100644 --- a/libunwind/include/libunwind.h +++ b/libunwind/include/libunwind.h @@ -119,6 +119,9 @@ __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \ __ptrauth_unwind_cie_info_personality_disc) +// ptrauth_string_discriminator("personality") == 0x7EAD) + #define __ptrauth_unwind_pacret_personality_disc 0x7EAD + #else #define __ptrauth_unwind_upi_handler @@ -136,7 +139,6 @@ #define __ptrauth_unwind_uis_compact_unwind_section #define __ptrauth_unwind_uis_compact_unwind_section_length #define __ptrauth_unwind_cie_info_personality - #endif #if defined(_WIN32) && defined(__SEH__) diff --git a/libunwind/src/CompactUnwinder.hpp b/libunwind/src/CompactUnwinder.hpp index 272352a..041fa8a 100644 --- a/libunwind/src/CompactUnwinder.hpp +++ b/libunwind/src/CompactUnwinder.hpp @@ -683,17 +683,13 @@ int CompactUnwinder_arm64<A>::stepWithCompactEncodingFrame( } Registers_arm64::reg_t fp = registers.getFP(); - // fp points to old fp - registers.setFP(addressSpace.get64(fp)); - // old sp is fp less saved fp and lr. Set this before FP & LR because in - // arm64e it's the discriminator used for those registers. + // old sp is fp less saved fp and lr. Set this before LR because in arm64e + // it's the authentication discriminator. registers.setSP(fp + 16); - Registers_arm64::reg_t oldfp = addressSpace.get64(fp); - // fp points to old fp - registers.setFP(oldfp); + registers.setFP(addressSpace.get64(fp)); // pop return address into pc registers.setIP(addressSpace.get64(fp + 8)); diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp index b34d9d7..5370fe0 100644 --- a/libunwind/src/DwarfInstructions.hpp +++ b/libunwind/src/DwarfInstructions.hpp @@ -63,7 +63,7 @@ private: pint_t cfa, const RegisterLocation &savedReg); static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, - R ®isters) { + const R ®isters) { if (prolog.cfaRegister != 0) { uintptr_t cfaRegister = registers.getRegister((int)prolog.cfaRegister); return (pint_t)(cfaRegister + prolog.cfaRegisterOffset); @@ -209,7 +209,7 @@ bool DwarfInstructions<A, R>::isReturnAddressSignedWithPC(A &addressSpace, template <typename A, typename R> int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, - typename R::link_reg_t &pc, + const typename R::link_reg_t &pc, pint_t fdeStart, R ®isters, bool &isSignalFrame, bool stage2) { FDE_Info fdeInfo; @@ -302,12 +302,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, isSignalFrame = cieInfo.isSignalFrame; -#if defined(_LIBUNWIND_TARGET_AARCH64) - // If the target is aarch64 then the return address may have been signed - // using the v8.3 pointer authentication extensions. The original - // return address needs to be authenticated before the return address is - // restored. autia1716 is used instead of autia as autia1716 assembles - // to a NOP on pre-v8.3a architectures. +#if defined(__ARM64E__) + // If the target is using the arm64e ABI then the return address has + // been signed using the stack pointer as a diversifier. The original + // return address needs to be authenticated before the it is restored. + // autia1716 is used instead of autia as autia1716 assembles to a NOP on + // pre-v8.3a architectures. if ((R::getArch() == REGISTERS_ARM64) && isReturnAddressSigned(addressSpace, registers, cfa, prolog) && returnAddress != 0) { diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp index 25f0ee4..fe20030 100644 --- a/libunwind/src/DwarfParser.hpp +++ b/libunwind/src/DwarfParser.hpp @@ -405,6 +405,12 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie, // schema. If we could guarantee the encoding of the personality we // could avoid this by simply giving resultAddr the correct ptrauth // schema and performing an assignment. +#ifdef __ARM64E__ + const auto oldDiscriminator = resultAddr; +#else + const auto oldDiscriminator = ptrauth_blend_discriminator( + (void*)resultAddr, __ptrauth_unwind_pacret_personality_disc); +#endif const auto discriminator = ptrauth_blend_discriminator( &cieInfo->personality, __ptrauth_unwind_cie_info_personality_disc); void *signedPtr = ptrauth_auth_and_resign( |