From 26c48dbf44f094bd1d28342ac4f10de4a2764464 Mon Sep 17 00:00:00 2001 From: Lexi Shao Date: Sat, 29 May 2021 14:43:09 +0800 Subject: [PATCH] livepatch/ppc64: Ignore the first frame when checking stack rtos inclusion category: bugfix bugzilla: 42399/46793/51924 CVE: NA ---------------------------------------- According to function _switch in entry_32/64.S, for non-current and not-in-interrupt task, the LR is saved in the LR position in the 2nd frame. The content in LR position in the 1st frame is not filled, so it is left by previous stack frames and may be an address in a kernel function, resulting in failure in applying a kernel patch even when the target function is not actually in stack. Therefore, we should ignore the first frame to get a more reliable backtrace. Signed-off-by: Lexi Shao Reviewed-by: Cheng Jian Signed-off-by: yangerkun Signed-off-by: Dong Kai Signed-off-by: Ye Weihua Reviewed-by: Yang Jihong Signed-off-by: Zheng Zengkai --- arch/powerpc/kernel/livepatch_64.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/livepatch_64.c b/arch/powerpc/kernel/livepatch_64.c index 0fdfe080b7f1..cb9f9035f315 100644 --- a/arch/powerpc/kernel/livepatch_64.c +++ b/arch/powerpc/kernel/livepatch_64.c @@ -304,7 +304,17 @@ int klp_check_calltrace(struct klp_patch *patch, int enable) */ continue; } else { - stack = (unsigned long *)t->thread.ksp; + /* + * Skip the first frame since it does not contain lr + * at notmal position and nip is store ind the lr + * position in the second frame. + * See arch/powerpc/kernel/entry_64.S _switch . + */ + unsigned long s = *(unsigned long *)t->thread.ksp; + + if (!validate_sp(s, t, STACK_FRAME_OVERHEAD)) + continue; + stack = (unsigned long *)s; } frame.sp = (unsigned long)stack; -- GitLab