From: Mark Rutland mark.rutland@arm.com
mainline inclusion from v5.7-rc1 commit 04ad99a0b160 category: feature bugzilla: 27615 CVE: NA
-------------------------------------------------
When we enable pointer authentication in the kernel, LR values saved to the stack will have a PAC which we must strip in order to retrieve the real return address.
Strip PACs when unwinding the stack in order to account for this.
When function graph tracer is used with patchable-function-entry then return_to_handler will also have pac bits so strip it too.
Reviewed-by: Kees Cook keescook@chromium.org Acked-by: Catalin Marinas catalin.marinas@arm.com Reviewed-by: James Morse james.morse@arm.com Signed-off-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Kristina Martsenko kristina.martsenko@arm.com [Amit: Re-position ptrauth_strip_insn_pac, comment] Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com
Conflicts: arch/arm64/kernel/stacktrace.c [Zheng Zengkai: fix conflicts caused by skipping the following commit. a44827 arm64: Use ftrace_graph_get_ret_stack() instead of curr_ret_stack 421d10 arm64: function_graph: Remove use of FTRACE_NOTRACE_DEPTH]
Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/kernel/stacktrace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index bb482ec044b61..7f266b8d1b2b0 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -25,6 +25,7 @@ #include <linux/stacktrace.h>
#include <asm/irq.h> +#include <asm/pointer_auth.h> #include <asm/stack_pointer.h> #include <asm/stacktrace.h>
@@ -59,7 +60,7 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER if (tsk->ret_stack && - (frame->pc == (unsigned long)return_to_handler)) { + (ptrauth_strip_insn_pac(frame->pc) == (unsigned long)return_to_handler)) { if (WARN_ON_ONCE(frame->graph == -1)) return -EINVAL; if (frame->graph < -1) @@ -75,6 +76,8 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+ frame->pc = ptrauth_strip_insn_pac(frame->pc); + /* * Frames created upon entry from EL0 have NULL FP and PC values, so * don't bother reporting these. Frames created by __noreturn functions