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 <[email protected]> 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; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
