-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[runtimes][PAC] Harden unwinding when possible #143230
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
Conversation
@llvm/pr-subscribers-pgo @llvm/pr-subscribers-libunwind Author: Oliver Hunt (ojhunt) ChangesThis hardens the unwinding logic and datastructures on systems that support pointer authentication. The approach taken to hardening is to harden the schemas of as many high value fields in the myriad structs as possible, and then also explicitly qualify local variables referencing privileged or security critical values. This ABI is exposed to the personality functions, and so updating to conform to that is a mandatory change, but to reduce the risk of oracles, the adoption also hardened the locals and datastructures in compiler-rt and libcxxabi. We're gating these on Patch is 51.36 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/143230.diff 14 Files Affected:
diff --git a/compiler-rt/lib/builtins/gcc_personality_v0.c b/compiler-rt/lib/builtins/gcc_personality_v0.c
index ef63a5fb83472..42b992949d2cc 100644
--- a/compiler-rt/lib/builtins/gcc_personality_v0.c
+++ b/compiler-rt/lib/builtins/gcc_personality_v0.c
@@ -30,6 +30,45 @@ EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT,
_Unwind_Personality_Fn);
#endif
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#endif
+
+#if defined(__APPLE__) && __has_feature(ptrauth_qualifier)
+#if __has_feature(ptrauth_restricted_intptr_qualifier)
+#define PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(key, addressDiscriminated, \
+ discriminatorString) \
+ __ptrauth_restricted_intptr(key, addressDiscriminated, \
+ ptrauth_string_discriminator(discriminatorString))
+#else
+#define PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(key, addressDiscriminated, \
+ discriminatorString) \
+ __ptrauth(key, addressDiscriminated, \
+ ptrauth_string_discriminator(discriminatorString))
+#endif
+#else
+#define PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(key, addressDiscriminated, \
+ discriminatorString)
+#endif
+
+// Helper wrappers for pointer auth qualifiers because we use a lot of variants
+// Suffixes:
+// * PDC : ptrauth_key_process_dependent_code
+// * RA : ptrauth_key_return_address
+// * FN : ptrauth_key_function_pointer
+#define PERSONALITY_PTRAUTH_RI_FN(__discriminator) \
+ PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(ptrauth_key_function_pointer, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+#define PERSONALITY_PTRAUTH_RI_PDC(__discriminator) \
+ PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(ptrauth_key_process_dependent_code, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+#define PERSONALITY_PTRAUTH_RI_RA(__discriminator) \
+ PERSONALITY_PTRAUTH_RESTRICTED_INTPTR(ptrauth_key_return_address, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+
// Pointer encodings documented at:
// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
@@ -205,7 +244,8 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
return continueUnwind(exceptionObject, context);
uintptr_t pc = (uintptr_t)_Unwind_GetIP(context) - 1;
- uintptr_t funcStart = (uintptr_t)_Unwind_GetRegionStart(context);
+ uintptr_t PERSONALITY_PTRAUTH_RI_FN("__gcc_personality_v0'funcStart")
+ funcStart = (uintptr_t)_Unwind_GetRegionStart(context);
uintptr_t pcOffset = pc - funcStart;
// Parse LSDA header.
@@ -224,11 +264,14 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
const uint8_t *callSiteTableEnd = callSiteTableStart + callSiteTableLength;
const uint8_t *p = callSiteTableStart;
while (p < callSiteTableEnd) {
- uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
- size_t length = readEncodedPointer(&p, callSiteEncoding);
- size_t landingPad = readEncodedPointer(&p, callSiteEncoding);
+ uintptr_t PERSONALITY_PTRAUTH_RI_PDC("__gcc_personality_v0'start")
+ start = readEncodedPointer(&p, callSiteEncoding);
+ size_t PERSONALITY_PTRAUTH_RI_PDC("__gcc_personality_v0'length")
+ length = readEncodedPointer(&p, callSiteEncoding);
+ size_t PERSONALITY_PTRAUTH_RI_PDC("__gcc_personality_v0'landingPadOffset")
+ landingPadOffset = readEncodedPointer(&p, callSiteEncoding);
readULEB128(&p); // action value not used for C code
- if (landingPad == 0)
+ if (landingPadOffset == 0)
continue; // no landing pad for this entry
if ((start <= pcOffset) && (pcOffset < (start + length))) {
// Found landing pad for the PC.
@@ -238,7 +281,21 @@ COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
(uintptr_t)exceptionObject);
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
- _Unwind_SetIP(context, (funcStart + landingPad));
+#define LANDING_PAD_DISCRIMINATOR "__gcc_personality_v0'landingPad"
+ size_t PERSONALITY_PTRAUTH_RI_RA(LANDING_PAD_DISCRIMINATOR)
+ landingPad = funcStart + landingPadOffset;
+#if defined(__APPLE__) && __has_feature(ptrauth_qualifier)
+ uintptr_t stack_pointer = _Unwind_GetGR(context, -2);
+ const uintptr_t existingDiscriminator = ptrauth_blend_discriminator(
+ &landingPad,
+ ptrauth_string_discriminator(LANDING_PAD_DISCRIMINATOR));
+ uintptr_t newIP = (uintptr_t)ptrauth_auth_and_resign(
+ *(void **)&landingPad, ptrauth_key_function_pointer,
+ existingDiscriminator, ptrauth_key_return_address, stack_pointer);
+ _Unwind_SetIP(context, newIP);
+#else
+ _Unwind_SetIP(context, landingPad);
+#endif
return _URC_INSTALL_CONTEXT;
}
}
diff --git a/compiler-rt/lib/profile/InstrProfilingValue.c b/compiler-rt/lib/profile/InstrProfilingValue.c
index a608d41d39e77..cd6ae3d7a4248 100644
--- a/compiler-rt/lib/profile/InstrProfilingValue.c
+++ b/compiler-rt/lib/profile/InstrProfilingValue.c
@@ -83,7 +83,13 @@ __llvm_profile_iterate_data(const __llvm_profile_data *Data) {
/* This method is only used in value profiler mock testing. */
COMPILER_RT_VISIBILITY void *
__llvm_get_function_addr(const __llvm_profile_data *Data) {
- return Data->FunctionPointer;
+ void *FP = Data->FunctionPointer;
+#if __has_feature(ptrauth_calls)
+ // This is only used for tests where we compare against what happens to be
+ // signed pointers.
+ FP = ptrauth_sign_unauthenticated(FP, VALID_CODE_KEY, 0);
+#endif
+ return FP;
}
/* Allocate an array that holds the pointers to the linked lists of
diff --git a/libcxxabi/include/__cxxabi_config.h b/libcxxabi/include/__cxxabi_config.h
index 759445dac91f9..e67d065fe57f3 100644
--- a/libcxxabi/include/__cxxabi_config.h
+++ b/libcxxabi/include/__cxxabi_config.h
@@ -32,7 +32,8 @@
#endif
#if defined(_WIN32)
- #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) || (defined(__MINGW32__) && !defined(_LIBCXXABI_BUILDING_LIBRARY))
+ #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) || \
+ (defined(__MINGW32__) && !defined(_LIBCXXABI_BUILDING_LIBRARY))
#define _LIBCXXABI_HIDDEN
#define _LIBCXXABI_DATA_VIS
#define _LIBCXXABI_FUNC_VIS
@@ -109,4 +110,49 @@
# define _LIBCXXABI_NOEXCEPT noexcept
#endif
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#endif
+
+#if defined(__APPLE__) && __has_feature(ptrauth_qualifier)
+# define _LIBCXXABI_PTRAUTH(__key, __address_discriminated, __discriminator) \
+ __ptrauth(__key,__address_discriminated, \
+ ptrauth_string_discriminator(__discriminator))
+// This work around is required to support divergence in spelling
+// during the ptrauth upstreaming process.
+# if __has_feature(ptrauth_restricted_intptr_qualifier)
+# define _LIBCXXABI_PTRAUTH_RESTRICTED_INTPTR(__key, __address_discriminated, \
+ __discriminator) \
+ __ptrauth_restricted_intptr(__key,__address_discriminated, \
+ ptrauth_string_discriminator(__discriminator))
+# else
+# define _LIBCXXABI_PTRAUTH_RESTRICTED_INTPTR(__key, __address_discriminated, \
+ __discriminator) \
+ __ptrauth(__key,__address_discriminated, \
+ ptrauth_string_discriminator(__discriminator))
+# endif
+#else
+# define _LIBCXXABI_PTRAUTH(__key, __address_discriminated, __discriminator)
+# define _LIBCXXABI_PTRAUTH_RESTRICTED_INTPTR(__key, __address_discriminated, \
+ __discriminator)
+#endif
+
+// Helper wrappers for pointer auth qualifiers because we use a lot of variants
+// Suffixes:
+// * _RI : qualifier is __ptrauth_restricted_intptr
+// * PDD : key is ptrauth_key_process_dependent_data
+// * FN : key is ptrauth_key_function_pointer
+#define _LIBCXXABI_PTRAUTH_PDD(__discriminator) \
+ _LIBCXXABI_PTRAUTH(ptrauth_key_process_dependent_data, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+#define _LIBCXXABI_PTRAUTH_FN(__discriminator) \
+ _LIBCXXABI_PTRAUTH(ptrauth_key_function_pointer, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+#define _LIBCXXABI_PTRAUTH_RI_PDD(__discriminator) \
+ _LIBCXXABI_PTRAUTH_RESTRICTED_INTPTR(ptrauth_key_process_dependent_data, \
+ /*__address_discriminated=*/1, \
+ __discriminator)
+
#endif // ____CXXABI_CONFIG_H
diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h
index aba08f2992103..4c69d48048f02 100644
--- a/libcxxabi/src/cxa_exception.h
+++ b/libcxxabi/src/cxa_exception.h
@@ -47,10 +47,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
// In Wasm, a destructor returns its argument
void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
#else
- void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
+ void(_LIBCXXABI_DTOR_FUNC* _LIBCXXABI_PTRAUTH_FN("__cxa_exception::exceptionDestructor") exceptionDestructor)(void*);
#endif
- std::unexpected_handler unexpectedHandler;
- std::terminate_handler terminateHandler;
+ std::unexpected_handler _LIBCXXABI_PTRAUTH_FN("__cxa_exception::unexpectedHandler") unexpectedHandler;
+ std::terminate_handler _LIBCXXABI_PTRAUTH_FN("__cxa_exception::terminateHandler") terminateHandler;
__cxa_exception *nextException;
@@ -61,10 +61,10 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
int propagationCount;
#else
int handlerSwitchValue;
- const unsigned char *actionRecord;
- const unsigned char *languageSpecificData;
- void *catchTemp;
- void *adjustedPtr;
+ const unsigned char* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::actionRecord") actionRecord;
+ const unsigned char* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::languageSpecificData") languageSpecificData;
+ void* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::catchTemp") catchTemp;
+ void* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::adjustedPtr") adjustedPtr;
#endif
#if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI)
@@ -79,6 +79,8 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
// The layout of this structure MUST match the layout of __cxa_exception, with
// primaryException instead of referenceCount.
+// The tags used in the pointer authentication qualifiers also need to match
+// those of the corresponding members in __cxa_exception.
struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
#if defined(__LP64__) || defined(_WIN64) || defined(_LIBCXXABI_ARM_EHABI)
void* reserve; // padding.
@@ -86,9 +88,9 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
#endif
std::type_info *exceptionType;
- void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
- std::unexpected_handler unexpectedHandler;
- std::terminate_handler terminateHandler;
+ void(_LIBCXXABI_DTOR_FUNC* _LIBCXXABI_PTRAUTH_FN("__cxa_exception::exceptionDestructor") exceptionDestructor)(void*);
+ std::unexpected_handler _LIBCXXABI_PTRAUTH_FN("__cxa_exception::unexpectedHandler") unexpectedHandler;
+ std::terminate_handler _LIBCXXABI_PTRAUTH_FN("__cxa_exception::terminateHandler") terminateHandler;
__cxa_exception *nextException;
@@ -99,10 +101,10 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
int propagationCount;
#else
int handlerSwitchValue;
- const unsigned char *actionRecord;
- const unsigned char *languageSpecificData;
- void * catchTemp;
- void *adjustedPtr;
+ const unsigned char* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::actionRecord") actionRecord;
+ const unsigned char* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::languageSpecificData") languageSpecificData;
+ void* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::catchTemp") catchTemp;
+ void* _LIBCXXABI_PTRAUTH_PDD("__cxa_exception::adjustedPtr") 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 5f6e75c5be19c..cbb3f46e0f55c 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -22,6 +22,12 @@
#include "private_typeinfo.h"
#include "unwind.h"
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#endif
+
+#include "libunwind.h"
+
// TODO: This is a temporary workaround for libc++abi to recognize that it's being
// built against LLVM's libunwind. LLVM's libunwind started reporting _LIBUNWIND_VERSION
// in LLVM 15 -- we can remove this workaround after shipping LLVM 17. Once we remove
@@ -527,12 +533,19 @@ get_thrown_object_ptr(_Unwind_Exception* unwind_exception)
namespace
{
+#define _LIBCXXABI_PTRAUTH_KEY ptrauth_key_process_dependent_code
+typedef const uint8_t* _LIBCXXABI_PTRAUTH_PDD("scan_results::languageSpecificData") lsd_ptr_t;
+typedef const uint8_t* _LIBCXXABI_PTRAUTH_PDD("scan_results::actionRecord") action_ptr_t;
+#define _LIBCXXABI_PTRAUTH_SCANRESULT_LANDINGPAD_DISC "scan_results::landingPad"
+typedef uintptr_t _LIBCXXABI_PTRAUTH_RI_PDD(_LIBCXXABI_PTRAUTH_SCANRESULT_LANDINGPAD_DISC) landing_pad_t;
+typedef void* _LIBCXXABI_PTRAUTH_PDD(_LIBCXXABI_PTRAUTH_SCANRESULT_LANDINGPAD_DISC) landing_pad_ptr_t;
+
struct scan_results
{
int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
- const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance.
- const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected
- uintptr_t landingPad; // null -> nothing found, else something found
+ action_ptr_t actionRecord; // Currently unused. Retained to ease future maintenance.
+ lsd_ptr_t languageSpecificData; // Needed only for __cxa_call_unexpected
+ landing_pad_t landingPad; // null -> nothing found, else something found
void* adjustedPtr; // Used in cxa_exception.cpp
_Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR,
// _URC_FATAL_PHASE2_ERROR,
@@ -541,7 +554,33 @@ struct scan_results
};
} // unnamed namespace
+}
+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.
+template <typename PtrType>
+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;
+ } u;
+ u.as_landing_pad = &results.landingPad;
+ *u.as_pointer = out;
+}
+
+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;
+ } u;
+ u.as_landing_pad = &results.landingPad;
+ return *u.as_pointer;
+}
+} // unnamed namespace
+
+extern "C" {
static
void
set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
@@ -557,7 +596,22 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
reinterpret_cast<uintptr_t>(unwind_exception));
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
static_cast<uintptr_t>(results.ttypeIndex));
+#if defined(__APPLE__) && __has_feature(ptrauth_qualifier)
+ auto stack_pointer = _Unwind_GetGR(context, UNW_REG_SP);
+ // We manually re-sign the IP as the __ptrauth qualifiers cannot
+ // express the required relationship with the destination address
+ const auto existingDiscriminator = ptrauth_blend_discriminator(
+ &results.landingPad,
+ ptrauth_string_discriminator(_LIBCXXABI_PTRAUTH_SCANRESULT_LANDINGPAD_DISC));
+ unw_word_t newIP = (unw_word_t)ptrauth_auth_and_resign(*(void**)&results.landingPad,
+ _LIBCXXABI_PTRAUTH_KEY,
+ existingDiscriminator,
+ ptrauth_key_return_address,
+ stack_pointer);
+ _Unwind_SetIP(context, newIP);
+#else
_Unwind_SetIP(context, results.landingPad);
+#endif
}
/*
@@ -691,12 +745,12 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
// The call sites are ordered in increasing value of start
uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
- uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
+ landing_pad_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
uintptr_t actionEntry = readULEB128(&callSitePtr);
if ((start <= ipOffset) && (ipOffset < (start + length)))
#else // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__
// ip is 1-based index into this table
- uintptr_t landingPad = readULEB128(&callSitePtr);
+ landing_pad_t landingPad = readULEB128(&callSitePtr);
uintptr_t actionEntry = readULEB128(&callSitePtr);
if (--ip == 0)
#endif // __USING_SJLJ_EXCEPTIONS__ || __WASM_EXCEPTIONS__
@@ -935,8 +989,7 @@ __gxx_personality_v0
results.ttypeIndex = exception_header->handlerSwitchValue;
results.actionRecord = exception_header->actionRecord;
results.languageSpecificData = exception_header->languageSpecificData;
- results.landingPad =
- reinterpret_cast<uintptr_t>(exception_header->catchTemp);
+ set_landing_pad_as_ptr(results, exception_header->catchTemp);
results.adjustedPtr = exception_header->adjustedPtr;
// Jump to the handler.
@@ -970,7 +1023,7 @@ __gxx_personality_v0
exc->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
exc->actionRecord = results.actionRecord;
exc->languageSpecificData = results.languageSpecificData;
- exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
+ exc->catchTemp = get_landing_pad_as_ptr(results);
exc->adjustedPtr = results.adjustedPtr;
#ifdef __WASM_EXCEPTIONS__
// Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the
diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index b2dae8feed9a3..e7375bbca1b3d 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -43,6 +43,61 @@
#define LIBUNWIND_AVAIL
#endif
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#endif
+
+#if defined(__APPLE__) && __has_feature(ptrauth_qualifier)
+#define _LIBUNWIND_PTRAUTH(__key, __address_discriminated, __discriminator) \
+ __ptrauth(__key, __address_discriminated, \
+ ptrauth_string_discriminator(__discriminator))
+// This work around is required to support divergence in spelling
+// developed during the ptrauth upstreaming process.
+#if __has_feature(ptrauth_restricted_intptr_qualifier)
+#define _LIBUNWIND_PTRAUTH_RESTRICTED_INTPTR(__key, __address_discriminated, \
+ __discriminator) \
+ __ptrauth_restricted_intptr(__key, __address_discriminated, \
+ ptrauth_string_discriminator(__discriminator...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions hpp,cpp,c,h -- compiler-rt/lib/builtins/gcc_personality_v0.c libcxxabi/include/__cxxabi_config.h libcxxabi/src/cxa_exception.cpp libcxxabi/src/cxa_exception.h libcxxabi/src/cxa_personality.cpp libunwind/include/__libunwind_config.h libunwind/include/libunwind.h libunwind/src/AddressSpace.hpp libunwind/src/CompactUnwinder.hpp libunwind/src/DwarfInstructions.hpp libunwind/src/DwarfParser.hpp libunwind/src/Registers.hpp libunwind/src/UnwindCursor.hpp libunwind/src/UnwindLevel1.c libunwind/src/libunwind.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h
index fa4c4dc55..9c495e668 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;
@@ -101,10 +101,10 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_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)
diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index b7eb0f23d..b2168067a 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -567,17 +567,17 @@ 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
{
int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
- action_ptr_t actionRecord; // Currently unused. Retained to ease future maintenance.
- lsd_ptr_t languageSpecificData; // Needed only for __cxa_call_unexpected
- landing_pad_t landingPad; // null -> nothing found, else something found
+ action_ptr_t actionRecord; // Currently unused. Retained to ease future maintenance.
+ lsd_ptr_t languageSpecificData; // Needed only for __cxa_call_unexpected
+ landing_pad_t landingPad; // null -> nothing found, else something found
void* adjustedPtr; // Used in cxa_exception.cpp
_Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR,
// _URC_FATAL_PHASE2_ERROR,
@@ -607,14 +607,10 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
// We manually re-sign the IP as the __ptrauth qualifiers cannot
// express the required relationship with the destination address
const auto existingDiscriminator =
- ptrauth_blend_discriminator(&results.landingPad,
- __ptrauth_scan_results_landingpad_disc);
+ ptrauth_blend_discriminator(&results.landingPad, __ptrauth_scan_results_landingpad_disc);
unw_word_t newIP /* opaque __ptrauth(ptrauth_key_return_address, stackPointer, 0) */ =
- (unw_word_t)ptrauth_auth_and_resign(*(void* const*)&results.landingPad,
- __ptrauth_scan_results_landingpad_key,
- existingDiscriminator,
- ptrauth_key_return_address,
- stackPointer);
+ (unw_word_t)ptrauth_auth_and_resign(*(void* const*)&results.landingPad, __ptrauth_scan_results_landingpad_key,
+ existingDiscriminator, ptrauth_key_return_address, stackPointer);
_Unwind_SetIP(context, newIP);
#else
_Unwind_SetIP(context, results.landingPad);
@@ -971,51 +967,37 @@ _UA_CLEANUP_PHASE
// trivial value union to coerce the types so instead we perform the re-signing
// manually.
using __cxa_catch_temp_type = decltype(__cxa_exception::catchTemp);
-static inline void set_landing_pad(scan_results& results,
- const __cxa_catch_temp_type& source) {
-#if __has_feature(ptrauth_calls)
- const uintptr_t sourceDiscriminator =
- ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc);
+static inline void set_landing_pad(scan_results& results, const __cxa_catch_temp_type& source) {
+# if __has_feature(ptrauth_calls)
+ const uintptr_t sourceDiscriminator = ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc);
const uintptr_t targetDiscriminator =
- ptrauth_blend_discriminator(&results.landingPad,
- __ptrauth_scan_results_landingpad_disc);
- uintptr_t reauthenticatedLandingPad =
- (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast<void* const*>(&source),
- __ptrauth_cxxabi_catch_temp_key,
- sourceDiscriminator,
- __ptrauth_scan_results_landingpad_key,
- targetDiscriminator);
- memmove(reinterpret_cast<void *>(&results.landingPad),
- reinterpret_cast<void *>(&reauthenticatedLandingPad),
+ ptrauth_blend_discriminator(&results.landingPad, __ptrauth_scan_results_landingpad_disc);
+ uintptr_t reauthenticatedLandingPad = (uintptr_t)ptrauth_auth_and_resign(
+ *reinterpret_cast<void* const*>(&source), __ptrauth_cxxabi_catch_temp_key, sourceDiscriminator,
+ __ptrauth_scan_results_landingpad_key, targetDiscriminator);
+ memmove(reinterpret_cast<void*>(&results.landingPad), reinterpret_cast<void*>(&reauthenticatedLandingPad),
sizeof(reauthenticatedLandingPad));
-#else
+# else
results.landingPad = reinterpret_cast<landing_pad_t>(source);
-#endif
+# endif
}
-static inline void get_landing_pad(__cxa_catch_temp_type &dest,
- const scan_results &results) {
-#if __has_feature(ptrauth_calls)
+static inline void get_landing_pad(__cxa_catch_temp_type& dest, const scan_results& results) {
+# if __has_feature(ptrauth_calls)
const uintptr_t sourceDiscriminator =
- ptrauth_blend_discriminator(&results.landingPad,
- __ptrauth_scan_results_landingpad_disc);
- const uintptr_t targetDiscriminator =
- ptrauth_blend_discriminator(&dest, __ptrauth_cxxabi_catch_temp_disc);
- uintptr_t reauthenticatedPointer =
- (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast<void* const*>(&results.landingPad),
- __ptrauth_scan_results_landingpad_key,
- sourceDiscriminator,
- __ptrauth_cxxabi_catch_temp_key,
- targetDiscriminator);
- memmove(reinterpret_cast<void *>(&dest),
- reinterpret_cast<void *>(&reauthenticatedPointer),
+ ptrauth_blend_discriminator(&results.landingPad, __ptrauth_scan_results_landingpad_disc);
+ const uintptr_t targetDiscriminator = ptrauth_blend_discriminator(&dest, __ptrauth_cxxabi_catch_temp_disc);
+ uintptr_t reauthenticatedPointer = (uintptr_t)ptrauth_auth_and_resign(
+ *reinterpret_cast<void* const*>(&results.landingPad), __ptrauth_scan_results_landingpad_key, sourceDiscriminator,
+ __ptrauth_cxxabi_catch_temp_key, targetDiscriminator);
+ memmove(reinterpret_cast<void*>(&dest), reinterpret_cast<void*>(&reauthenticatedPointer),
sizeof(reauthenticatedPointer));
-#else
+# else
dest = reinterpret_cast<__cxa_catch_temp_type>(results.landingPad);
-#endif
+# endif
}
-#ifdef __WASM_EXCEPTIONS__
+# ifdef __WASM_EXCEPTIONS__
_Unwind_Reason_Code __gxx_personality_wasm0
#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
static _Unwind_Reason_Code __gxx_personality_imp
diff --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h
index 343934e88..6595222f0 100644
--- a/libunwind/include/__libunwind_config.h
+++ b/libunwind/include/__libunwind_config.h
@@ -213,9 +213,9 @@
#endif // _LIBUNWIND_IS_NATIVE_ONLY
#if __has_feature(ptrauth_calls) && __has_feature(ptrauth_returns)
-# define _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING 1
+#define _LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING 1
#elif __has_feature(ptrauth_calls) != __has_feature(ptrauth_returns)
-# error "Either both or none of ptrauth_calls and ptrauth_returns "\
+#error "Either both or none of ptrauth_calls and ptrauth_returns "\
"is allowed to be enabled"
#endif
diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 18684ce31..1c7ec70c6 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -45,104 +45,119 @@
#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
- #include <ptrauth.h>
-
- // `__ptrauth_restricted_intptr` is a feature of apple clang that predates
- // support for direct application of `__ptrauth` to integer types. This
- // guard is necessary to support compilation with those compiler.
- #if __has_extension(ptrauth_restricted_intptr_qualifier)
- #define __unwind_ptrauth_restricted_intptr(...) \
- __ptrauth_restricted_intptr(__VA_ARGS__)
- #else
- #define __unwind_ptrauth_restricted_intptr(...) \
- __ptrauth(__VA_ARGS__)
- #endif
-
- // ptrauth_string_discriminator("unw_proc_info_t::handler") == 0x7405
- #define __ptrauth_unwind_upi_handler_disc 0x7405
-
- #define __ptrauth_unwind_upi_handler \
- __ptrauth(ptrauth_key_function_pointer, 1, __ptrauth_unwind_upi_handler_disc)
-
- #define __ptrauth_unwind_upi_handler_intptr \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1,\
- __ptrauth_unwind_upi_handler_disc)
-
- // ptrauth_string_discriminator("unw_proc_info_t::start_ip") == 0xCA2C
- #define __ptrauth_unwind_upi_startip \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, 0xCA2C)
-
- // ptrauth_string_discriminator("unw_proc_info_t::end_ip") == 0xE183
- #define __ptrauth_unwind_upi_endip \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, 0xE183)
-
- // ptrauth_string_discriminator("unw_proc_info_t::lsda") == 0x83DE
- #define __ptrauth_unwind_upi_lsda \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x83DE)
-
- // ptrauth_string_discriminator("unw_proc_info_t::flags") == 0x79A1
- #define __ptrauth_unwind_upi_flags \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x79A1)
-
- // ptrauth_string_discriminator("unw_proc_info_t::unwind_info") == 0xC20C
- #define __ptrauth_unwind_upi_info \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0xC20C)
-
- // ptrauth_string_discriminator("unw_proc_info_t::extra") == 0x03DF
- #define __ptrauth_unwind_upi_extra \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x03DF)
-
- // ptrauth_string_discriminator("Registers_arm64::link_reg_t") == 0x8301
- #define __ptrauth_unwind_registers_arm64_link_reg \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_code, 1, 0x8301)
-
- // ptrauth_string_discriminator("UnwindInfoSections::dso_base") == 0x4FF5
- #define __ptrauth_unwind_uis_dso_base \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x4FF5)
-
- // ptrauth_string_discriminator("UnwindInfoSections::dwarf_section") == 0x4974
- #define __ptrauth_unwind_uis_dwarf_section \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x4974)
-
- // ptrauth_string_discriminator("UnwindInfoSections::dwarf_section_length") == 0x2A9A
- #define __ptrauth_unwind_uis_dwarf_section_length \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x2A9A)
-
- // ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section") == 0xA27B
- #define __ptrauth_unwind_uis_compact_unwind_section \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0xA27B)
-
- // ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section_length") == 0x5D0A
- #define __ptrauth_unwind_uis_compact_unwind_section_length \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, 0x5D0A)
-
- // ptrauth_string_discriminator("CIE_Info::personality") == 0x6A40
- #define __ptrauth_unwind_cie_info_personality_disc 0x6A40
- #define __ptrauth_unwind_cie_info_personality \
- __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \
- __ptrauth_unwind_cie_info_personality_disc)
+#include <ptrauth.h>
+
+// `__ptrauth_restricted_intptr` is a feature of apple clang that predates
+// support for direct application of `__ptrauth` to integer types. This
+// guard is necessary to support compilation with those compiler.
+#if __has_extension(ptrauth_restricted_intptr_qualifier)
+#define __unwind_ptrauth_restricted_intptr(...) \
+ __ptrauth_restricted_intptr(__VA_ARGS__)
+#else
+#define __unwind_ptrauth_restricted_intptr(...) __ptrauth(__VA_ARGS__)
+#endif
- // ptrauth_string_discriminator("personality") == 0x7EAD)
- #define __ptrauth_unwind_pauthtest_personality_disc 0x7EAD
+// ptrauth_string_discriminator("unw_proc_info_t::handler") == 0x7405
+#define __ptrauth_unwind_upi_handler_disc 0x7405
+
+#define __ptrauth_unwind_upi_handler \
+ __ptrauth(ptrauth_key_function_pointer, 1, __ptrauth_unwind_upi_handler_disc)
+
+#define __ptrauth_unwind_upi_handler_intptr \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer, 1, \
+ __ptrauth_unwind_upi_handler_disc)
+
+// ptrauth_string_discriminator("unw_proc_info_t::start_ip") == 0xCA2C
+#define __ptrauth_unwind_upi_startip \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, \
+ 0xCA2C)
+
+// ptrauth_string_discriminator("unw_proc_info_t::end_ip") == 0xE183
+#define __ptrauth_unwind_upi_endip \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_independent_code, 1, \
+ 0xE183)
+
+// ptrauth_string_discriminator("unw_proc_info_t::lsda") == 0x83DE
+#define __ptrauth_unwind_upi_lsda \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x83DE)
+
+// ptrauth_string_discriminator("unw_proc_info_t::flags") == 0x79A1
+#define __ptrauth_unwind_upi_flags \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x79A1)
+
+// ptrauth_string_discriminator("unw_proc_info_t::unwind_info") == 0xC20C
+#define __ptrauth_unwind_upi_info \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0xC20C)
+
+// ptrauth_string_discriminator("unw_proc_info_t::extra") == 0x03DF
+#define __ptrauth_unwind_upi_extra \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x03DF)
+
+// ptrauth_string_discriminator("Registers_arm64::link_reg_t") == 0x8301
+#define __ptrauth_unwind_registers_arm64_link_reg \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_code, 1, \
+ 0x8301)
+
+// ptrauth_string_discriminator("UnwindInfoSections::dso_base") == 0x4FF5
+#define __ptrauth_unwind_uis_dso_base \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x4FF5)
+
+// ptrauth_string_discriminator("UnwindInfoSections::dwarf_section") == 0x4974
+#define __ptrauth_unwind_uis_dwarf_section \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x4974)
+
+// ptrauth_string_discriminator("UnwindInfoSections::dwarf_section_length") ==
+// 0x2A9A
+#define __ptrauth_unwind_uis_dwarf_section_length \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x2A9A)
+
+// ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section") ==
+// 0xA27B
+#define __ptrauth_unwind_uis_compact_unwind_section \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0xA27B)
+
+// ptrauth_string_discriminator("UnwindInfoSections::compact_unwind_section_length")
+// == 0x5D0A
+#define __ptrauth_unwind_uis_compact_unwind_section_length \
+ __unwind_ptrauth_restricted_intptr(ptrauth_key_process_dependent_data, 1, \
+ 0x5D0A)
+
+// ptrauth_string_discriminator("CIE_Info::personality") == 0x6A40
+#define __ptrauth_unwind_cie_info_personality_disc 0x6A40
+#define __ptrauth_unwind_cie_info_personality \
+ __unwind_ptrauth_restricted_intptr( \
+ ptrauth_key_function_pointer, 1, \
+ __ptrauth_unwind_cie_info_personality_disc)
+
+// ptrauth_string_discriminator("personality") == 0x7EAD)
+#define __ptrauth_unwind_pauthtest_personality_disc 0x7EAD
#else
- #define __unwind_ptrauth_restricted_intptr(...)
- #define __ptrauth_unwind_upi_handler
- #define __ptrauth_unwind_upi_handler_intptr
- #define __ptrauth_unwind_upi_startip
- #define __ptrauth_unwind_upi_endip
- #define __ptrauth_unwind_upi_lsda
- #define __ptrauth_unwind_upi_flags
- #define __ptrauth_unwind_upi_info
- #define __ptrauth_unwind_upi_extra
- #define __ptrauth_unwind_registers_arm64_link_reg
- #define __ptrauth_unwind_uis_dso_base
- #define __ptrauth_unwind_uis_dwarf_section
- #define __ptrauth_unwind_uis_dwarf_section_length
- #define __ptrauth_unwind_uis_compact_unwind_section
- #define __ptrauth_unwind_uis_compact_unwind_section_length
- #define __ptrauth_unwind_cie_info_personality
+#define __unwind_ptrauth_restricted_intptr(...)
+#define __ptrauth_unwind_upi_handler
+#define __ptrauth_unwind_upi_handler_intptr
+#define __ptrauth_unwind_upi_startip
+#define __ptrauth_unwind_upi_endip
+#define __ptrauth_unwind_upi_lsda
+#define __ptrauth_unwind_upi_flags
+#define __ptrauth_unwind_upi_info
+#define __ptrauth_unwind_upi_extra
+#define __ptrauth_unwind_registers_arm64_link_reg
+#define __ptrauth_unwind_uis_dso_base
+#define __ptrauth_unwind_uis_dwarf_section
+#define __ptrauth_unwind_uis_dwarf_section_length
+#define __ptrauth_unwind_uis_compact_unwind_section
+#define __ptrauth_unwind_uis_compact_unwind_section_length
+#define __ptrauth_unwind_cie_info_personality
#endif
@@ -191,18 +206,23 @@ typedef double unw_fpreg_t;
#endif
struct unw_proc_info_t {
- unw_word_t __ptrauth_unwind_upi_startip start_ip; /* start address of function */
- unw_word_t __ptrauth_unwind_upi_endip end_ip; /* address after end of function */
- unw_word_t __ptrauth_unwind_upi_lsda lsda; /* address of language specific data area, */
- /* or zero if not used */
+ unw_word_t __ptrauth_unwind_upi_startip
+ start_ip; /* start address of function */
+ unw_word_t __ptrauth_unwind_upi_endip
+ end_ip; /* address after end of function */
+ unw_word_t __ptrauth_unwind_upi_lsda
+ lsda; /* address of language specific data area, */
+ /* or zero if not used */
unw_word_t __ptrauth_unwind_upi_handler_intptr handler;
- unw_word_t gp; /* not used */
- unw_word_t __ptrauth_unwind_upi_flags flags; /* not used */
- uint32_t format; /* compact unwind encoding, or zero if none */
- uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */
- unw_word_t __ptrauth_unwind_upi_info unwind_info; /* address of DWARF unwind info, or zero */
- unw_word_t __ptrauth_unwind_upi_extra extra; /* mach_header of mach-o image containing func */
+ unw_word_t gp; /* not used */
+ unw_word_t __ptrauth_unwind_upi_flags flags; /* not used */
+ uint32_t format; /* compact unwind encoding, or zero if none */
+ uint32_t unwind_info_size; /* size of DWARF unwind info, or zero if none */
+ unw_word_t __ptrauth_unwind_upi_info
+ unwind_info; /* address of DWARF unwind info, or zero */
+ unw_word_t __ptrauth_unwind_upi_extra
+ extra; /* mach_header of mach-o image containing func */
};
typedef struct unw_proc_info_t unw_proc_info_t;
diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 63f9cb367..f38dda47c 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -129,27 +129,24 @@ struct UnwindInfoSections {
defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \
defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
// No dso_base for SEH.
- uintptr_t __ptrauth_unwind_uis_dso_base
- dso_base = 0;
+ uintptr_t __ptrauth_unwind_uis_dso_base dso_base = 0;
#endif
#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
size_t text_segment_length;
#endif
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
- uintptr_t __ptrauth_unwind_uis_dwarf_section
- dwarf_section = 0;
- size_t __ptrauth_unwind_uis_dwarf_section_length
- dwarf_section_length = 0;
+ uintptr_t __ptrauth_unwind_uis_dwarf_section dwarf_section = 0;
+ size_t __ptrauth_unwind_uis_dwarf_section_length dwarf_section_length = 0;
#endif
#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
uintptr_t dwarf_index_section;
size_t dwarf_index_section_length;
#endif
#if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
- uintptr_t __ptrauth_unwind_uis_compact_unwind_section
- compact_unwind_section = 0;
+ uintptr_t __ptrauth_unwind_uis_compact_unwind_section compact_unwind_section =
+ 0;
size_t __ptrauth_unwind_uis_compact_unwind_section_length
- compact_unwind_section_length = 0;
+ compact_unwind_section_length = 0;
#endif
#if defined(_LIBUNWIND_ARM_EHABI)
uintptr_t arm_section;
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index 5a5b57835..fc8f03637 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -1863,29 +1863,25 @@ public:
uint64_t getSP() const { return _registers.__sp; }
void setSP(uint64_t value) { _registers.__sp = value; }
- uint64_t getIP() const {
+ uint64_t getIP() const {
uint64_t value = _registers.__pc;
#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
// Note the value of the PC was signed to its address in the register state
// but everyone else expects it to be sign by the SP, so convert on return.
- value = (uint64_t)ptrauth_auth_and_resign((void *)_registers.__pc,
- ptrauth_key_return_address,
- &_registers.__pc,
- ptrauth_key_return_address,
- getSP());
+ value = (uint64_t)ptrauth_auth_and_resign(
+ (void *)_registers.__pc, ptrauth_key_return_address, &_registers.__pc,
+ ptrauth_key_return_address, getSP());
#endif
return value;
}
- void setIP(uint64_t value) {
+ void setIP(uint64_t value) {
#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
// Note the value which was set should have been signed with the SP.
// We then resign with the slot we are being stored in to so that both SP
// and LR can't be spoofed at the same time.
- value = (uint64_t)ptrauth_auth_and_resign((void *)value,
- ptrauth_key_return_address,
- getSP(),
- ptrauth_key_return_address,
- &_registers.__pc);
+ value = (uint64_t)ptrauth_auth_and_resign(
+ (void *)value, ptrauth_key_return_address, getSP(),
+ ptrauth_key_return_address, &_registers.__pc);
#endif
_registers.__pc = value;
}
@@ -1898,10 +1894,9 @@ public:
link_reg_t *referenceAuthedLinkRegister) {
// If we are in an arm64/arm64e frame, then the PC should have been signed
// with the SP
- *referenceAuthedLinkRegister =
- (uint64_t)ptrauth_auth_data((void *)inplaceAuthedLinkRegister,
- ptrauth_key_return_address,
- _registers.__sp);
+ *referenceAuthedLinkRegister = (uint64_t)ptrauth_auth_data(
+ (void *)inplaceAuthedLinkRegister, ptrauth_key_return_address,
+ _registers.__sp);
}
#endif
diff --git a/libunwind/src/UnwindLevel1.c b/libunwind/src/UnwindLevel1.c
index b0cd60dfb..2cca0e438 100644
--- a/libunwind/src/UnwindLevel1.c
+++ b/libunwind/src/UnwindLevel1.c
@@ -97,10 +97,10 @@
// is possible as `_Unwind_Personality_Fn` is a standard function pointer, and
// as such is not address diversified.
static _Unwind_Personality_Fn get_handler_function(unw_proc_info_t *frameInfo) {
- uintptr_t __unwind_ptrauth_restricted_intptr(ptrauth_key_function_pointer,
- 0,
- ptrauth_function_pointer_type_discriminator(_Unwind_Personality_Fn))
- reauthenticatedIntegerHandler = frameInfo->handler;
+ uintptr_t __unwind_ptrauth_restricted_intptr(
+ ptrauth_key_function_pointer, 0,
+ ptrauth_function_pointer_type_discriminator(_Unwind_Personality_Fn))
+ reauthenticatedIntegerHandler = frameInfo->handler;
_Unwind_Personality_Fn handler;
memmove(&handler, (void *)&reauthenticatedIntegerHandler,
sizeof(_Unwind_Personality_Fn));
diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp
index 951d87db8..034129ada 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -136,9 +136,8 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
// For this to be generally usable we manually re-sign it to the
// directly supported schema:
// __ptrauth(ptrauth_key_return_address, 1, 0)
- unw_word_t
- __unwind_ptrauth_restricted_intptr(ptrauth_key_return_address, 1,
- 0) authenticated_value;
+ unw_word_t __unwind_ptrauth_restricted_intptr(
+ ptrauth_key_return_address, 1, 0) authenticated_value;
unw_word_t opaque_value = (uint64_t)ptrauth_auth_and_resign(
(void *)value, ptrauth_key_return_address, sp,
ptrauth_key_return_address, &authenticated_value);
|
6810396
to
637245f
Compare
@kovdan01 @atrosinenko Please take a look |
Updating formatting before review - had discussed with Louis and he expressed a preference for some of it, but this llvm.org style bot complains many other cases (likely a local config issue when I was trying to cleanup the downstream code. So I've updated with a direct clang-format fix. |
unused variable errors are likely fallout from refactoring and workaround removals I did as part of the prep, will do some cleanup/diagnostics work later this week. I mostly wanted to get this available to others to see whether they were ok adopting this rather than rolling their own version. |
@ojhunt JFYI: I've published a couple of small fixes I've applied locally at https://github.com/kovdan01/llvm-project/commits/pointer-authenticated-unwinding-fix0/. Maybe this would be useful |
I'd posted this to try and avoid too much duplicated work so it's highly possible some of these issues are due to me screwing up refactoring, cleanups, or the patch preparation. I'll get back to this after wg21 wraps up this week, so sorry for the delays. |
I'll be back to working on this later today - there's a pile of feedback, and a bunch of nonsense that I managed to accidentally accrue and/or re-format when pushing the PR so it will take a little time to unbreak that. It may be easiest to force push a repaired PR first and then address comments. I also realize that some of the breakage might be due to mismatched APPLE vs has_feature(actual_feature) |
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.
I have tested this patch on Linux with aarch64-linux-pauthtest
triple and custom-built sysroot, here are the results.
In my setup, the tests pass on the following modified branch: https://github.com/atrosinenko/llvm-project/commits/pointer-authenticated-unwinding-fix1/. It is based on https://github.com/kovdan01/llvm-project/commits/pointer-authenticated-unwinding-fix0/ with the following changes:
- Currently, several parts of the patch are only enabled on Apple targets. For testing purposes, I unconditionally enabled parts of this patch guarded by
defined(__APPLE__)
. - It turned out that
__has_feature(ptrauth_qualifier)
does not work in mainline, so I replaced it with__has_feature(ptrauth_intrinsics)
. I expect the correct solution proposed by @kovdan01 (replacing with__has_extension(ptrauth_qualifier)
) to behave identically. - The change to
compiler-rt/lib/profile/InstrProfilingValue.c
seems to be unrelated to libunwind - The most meaningful change is updating signing schemas is several places - see inline comments. Additionally, I had to update a few other places that I cannot add inline comments to
- in
Registers_arm64::getRegister
andRegisters_arm64::setRegister
, replace direct references to_registers.__pc
with calls togetIP()
andsetIP()
, correspondingly - disable the existing pauth-related logic in
DwarfInstructions<A, R>::stepWithDwarf
- in
The fact I'm worried about is whether implicit signing and authentication on accesses to __ptrauth
-qualified fields may introduce signing or authentication oracles usable by an attacker, since many values stored to these fields are initially non-signed. This is possibly mitigated by the fact that all these fields use address diversity with distinct integer discriminators and/or the original values are taken from read-only memory. On the other hand, discriminator computation, auth / sign intrinsic and load / store to memory are currently three separate operations when accessing a __ptrauth
-qualified field, thus spilling of intermediate values to the stack is possible. Furthermore, even if the non-signed value originates from a read-only memory, this is not expressed in LLVM IR terms, thus the optimization pipeline may transform sensitive instruction sequences in an unsafe way.
* Add note for `__ptrauth_restricted_intptr` * Rename confusing parameter in set_landing_pad_as_ptr * Rename __ptrauth_unwind_pacret_personality_disc to __ptrauth_unwind_pauthtest_personality_disc
Stop using unions to deal with the pointer auth cast semantics, instead perform manual re-signing. This means the templated helper functions no longer need to be templates and so don't need to be in a separated non-extern "C" block. Fixing up the comments.
e059e1c
to
0f2679a
Compare
Remaining formatting changes differ significantly from the surrounding code. I don't want to intermingle significant changes with formatting changes. |
gnahhhhhh why is a9d9113 apparently fixing the armv8 build? That implies something it assuming Arm64Registers is a POD type, and I can't work out where :-/ |
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.
@ojhunt Thanks for tons of fixes! We have one more usage of unions in libunwind.cpp which is technically UB.
I've proposed a fix for this. See commit a29af82 from my branch ptrauth-unwinding-2025-10-19
As soon as this is addressed, I have no other objections from my side regarding this PR. Thanks for a great work!
#include "dwarf2.h" | ||
#include "libunwind_ext.h" | ||
|
||
|
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.
Nit: unintended formatting change
libunwind/src/libunwind.cpp
Outdated
// This is important for ptrauth, otherwise the IP cannot be correctly | ||
// signed. | ||
// We re-sign to a more usable form and then use it directly. | ||
union { |
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.
Please avoid using unions here as well since reading from authenticated_value
while opaque_value
was the last assigned member is UB in C++.
I've prepared a fix which works on my side. You are welcome to just apply that if you are happy with the fix implementation. See commit a29af82 from my branch ptrauth-unwinding-2025-10-19
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.
LGTM, thanks!
@ojhunt, just in case it gets lost in the comments, the usage of https://godbolt.org/z/WW95ad5rP Can you fix or revert so that we can get this building again with GCC? |
Will fix momentarily. I guess gcc does not have |
So I'd guess we need to move this into some common (but private) header and reuse for |
I think polluting space with |
PR up at #164535 |
This hardens the unwinding logic and datastructures on systems
that support pointer authentication.
The approach taken to hardening is to harden the schemas of as many
high value fields in the myriad structs as possible, and then also
explicitly qualify local variables referencing privileged or security
critical values.
This does introduce ABI linkage between libcxx, libcxxabi, and
libunwind but those are in principle separate from the OS itself
so we've kept the schema definitions in the library specific headers
rather than ptrauth.h