[libunwind] [WIP][PAC][libunwind] Handle LR and IP signing around sigreturn frame (PR #184661)
Anatoly Trosinenko via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 4 10:51:50 PST 2026
https://github.com/atrosinenko created https://github.com/llvm/llvm-project/pull/184661
Support stepping through sigreturn frame in PtrAuth-protected libunwind.
Unfortunately, this involves signing non-protected IP value from sigcontext struct saved on the stack by the kernel.
>From de0862d35fb8abfbfcca4ac6990789d9119f532e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 4 Mar 2026 20:13:10 +0300
Subject: [PATCH] [WIP][PAC][libunwind] Handle LR and IP signing around
sigreturn frame
Support stepping through sigreturn frame in PtrAuth-protected libunwind.
Unfortunately, this involves signing non-protected IP value from
sigcontext struct saved on the stack by the kernel.
---
libunwind/src/UnwindCursor.hpp | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index ff92c9e0a844a..42efd92c074cd 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -2901,7 +2901,13 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
// - The PC is invalid and happens to point to unreadable or unmapped memory.
//
// [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S
- const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
+ typename R::reg_t rawPC = this->getReg(UNW_REG_IP);
+ typename R::link_reg_t pc;
+ _registers.loadAndAuthenticateLinkRegister(rawPC, &pc);
+#else
+ typename R::link_reg_t pc = this->getReg(UNW_REG_IP);
+#endif
// The PC might contain an invalid address if the unwind info is bad, so
// directly accessing it could cause a SIGSEGV.
if (!isReadableAddr(pc))
@@ -2944,8 +2950,14 @@ int UnwindCursor<A, R>::stepThroughSigReturn(Registers_arm64 &) {
static_cast<pint_t>(i * 8));
_registers.setRegister(UNW_AARCH64_X0 + i, value);
}
- _registers.setSP(_addressSpace.get64(sigctx + kOffsetSp));
- _registers.setIP(_addressSpace.get64(sigctx + kOffsetPc));
+ uint64_t sp = _addressSpace.get64(sigctx + kOffsetSp);
+ uint64_t ip = _addressSpace.get64(sigctx + kOffsetPc);
+#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
+ ip = (uint64_t)ptrauth_sign_unauthenticated((void *)ip,
+ ptrauth_key_return_address, sp);
+#endif
+ _registers.setSP(sp);
+ _registers.setIP(ip);
_isSignalFrame = true;
return UNW_STEP_SUCCESS;
}
More information about the cfe-commits
mailing list