Skip to content

Commit 63d119a

Browse files
committed
[libunwind][AArch64][ELF][PAC] Fix ptrauth-specific stuff
- Fix build when __APPLE__ is not defined and libc_private.h header is absent. - Do not treat GOT pointers as signed on ELF.
1 parent 8b4f9c1 commit 63d119a

File tree

4 files changed

+40
-23
lines changed

4 files changed

+40
-23
lines changed

libunwind/src/DwarfParser.hpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -387,16 +387,22 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
387387
.getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding,
388388
/*datarelBase=*/0, &resultAddr);
389389
#if __has_feature(ptrauth_calls)
390-
// The GOT for the personality function was signed address authenticated.
391-
// Resign is as a regular function pointer.
392-
if (cieInfo->personality) {
393-
void* signedPtr = ptrauth_auth_and_resign((void*)cieInfo->personality,
394-
ptrauth_key_function_pointer,
395-
resultAddr,
396-
ptrauth_key_function_pointer,
397-
0);
398-
cieInfo->personality = (__typeof(cieInfo->personality))signedPtr;
399-
}
390+
if (cieInfo->personality) {
391+
#ifdef __APPLE__
392+
// The GOT for the personality function was signed address
393+
// authenticated. Resign is as a regular function pointer.
394+
void* signedPtr = ptrauth_auth_and_resign((void*)cieInfo->personality,
395+
ptrauth_key_function_pointer,
396+
resultAddr,
397+
ptrauth_key_function_pointer,
398+
0);
399+
#else
400+
void* signedPtr = ptrauth_sign_unauthenticated((void*)cieInfo->personality,
401+
ptrauth_key_function_pointer,
402+
0);
403+
#endif
404+
cieInfo->personality = (__typeof(cieInfo->personality))signedPtr;
405+
}
400406
#endif
401407
break;
402408
case 'L':

libunwind/src/Registers.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
18861886
void normalizeNewLinkRegister(reg_t& linkRegister, unw_word_t procInfoFlags) {
18871887
(void)linkRegister;
18881888
(void)procInfoFlags;
1889-
#if __has_feature(ptrauth_calls)
1889+
#if __has_feature(ptrauth_calls) && defined(__APPLE__)
18901890
if (procInfoFlags == ProcInfoFlags_IsARM64Image) {
18911891
// If the current frame is arm64e then the LR should have been signed by
18921892
// the SP. In this case, we'll just leave it as is. For other frames,

libunwind/src/UnwindCursor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ class UnwindCursor : public AbstractUnwindCursor{
10301030
#endif
10311031

10321032
void setProcInfoFlags() {
1033-
#if __has_feature(ptrauth_calls)
1033+
#if __has_feature(ptrauth_calls) && defined(__APPLE__)
10341034
// If the extra field is set, then it is set to the mach header and we can use
10351035
// that to determine which flags to set
10361036
if (_info.extra) {

libunwind/src/libunwind.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "config.h"
1515
#include "libunwind_ext.h"
1616

17-
#if __has_feature(ptrauth_calls)
17+
#if __has_feature(ptrauth_calls) && defined(__APPLE__)
1818
#include <libc_private.h>
1919
#endif
2020

@@ -141,17 +141,28 @@ _LIBUNWIND_HIDDEN int __unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
141141
#if __has_feature(ptrauth_calls)
142142
// If we are in an arm64e frame, then the PC should have been signed with the sp
143143
{
144-
const mach_header_64 *mh = (const mach_header_64 *)info.extra;
145-
// Note, if we don't have mh, we assume this was created by unw_init_local inside
146-
// libunwind.dylib itself, and we know we are arm64e.
147-
pint_t pc = (pint_t)co->getReg(UNW_REG_IP);
148-
if ((mh->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64_E) {
149-
if (ptrauth_auth_and_resign((void*)pc, ptrauth_key_return_address, sp,
150-
ptrauth_key_return_address, sp) != (void*)pc) {
151-
abort_report_np("Bad unwind through arm64e (0x%llX, 0x%llX)->0x%llX\n",
152-
pc, sp, (pint_t)ptrauth_auth_data((void*)pc, ptrauth_key_return_address, sp));
153-
}
144+
pint_t pc = (pint_t)co->getReg(UNW_REG_IP);
145+
#ifdef __APPLE__
146+
const mach_header_64 *mh = (const mach_header_64 *)info.extra;
147+
// Note, if we don't have mh, we assume this was created by unw_init_local inside
148+
// libunwind.dylib itself, and we know we are arm64e.
149+
if ((mh->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64_E) {
150+
#else
151+
// FIXME: we should probably look at PAUTH ABI tag note section
152+
bool isAuthElf = true;
153+
if (isAuthElf) {
154+
#endif
155+
if (ptrauth_auth_and_resign((void*)pc, ptrauth_key_return_address, sp,
156+
ptrauth_key_return_address, sp) != (void*)pc) {
157+
#ifdef __APPLE__
158+
abort_report_np("Bad unwind through arm64e (0x%llX, 0x%llX)->0x%llX\n",
159+
pc, sp, (pint_t)ptrauth_auth_data((void*)pc, ptrauth_key_return_address, sp));
160+
#else
161+
// FIXME: we probably want to handle it somehow specially
162+
return UNW_EINVALIDIP;
163+
#endif
154164
}
165+
}
155166
}
156167
#endif
157168

0 commit comments

Comments
 (0)