summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-18 13:16:12 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-18 14:01:34 +0100
commit1b86960dc451412e7029b267e9e87536fdd554cb (patch)
treeb01b91b3844e0feadc0b9b547dddd1110ee76713
parent961913f45ff64ee68b689ae8070e1ab42108d02b (diff)
downloadlinux-stable-1b86960dc451412e7029b267e9e87536fdd554cb.tar.gz
linux-stable-1b86960dc451412e7029b267e9e87536fdd554cb.tar.bz2
linux-stable-1b86960dc451412e7029b267e9e87536fdd554cb.zip
Revert "x86: Fix get_wchan() to support the ORC unwinder"
This reverts commit f270511247a5b6257b84db17883e0b1189bf5e16 which is commit bc9bbb81730ea667c31c5b284f95ee312bab466f upstream. It has been reported to be causing problems, and is being reworked upstream and has been dropped from the current 5.15.y stable queue until it gets resolved. Reported-by: Chris Rankin <rankincj@gmail.com> Reported-by: Thorsten Leemhuis <linux@leemhuis.info> Link: https://lore.kernel.org/r/ed000478-2a60-0066-c337-a04bffc112b1@leemhuis.info Cc: Qi Zheng <zhengqi.arch@bytedance.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Kees Cook <keescook@chromium.org> Cc: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/kernel/process.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index cd426c3283ee..f2f733bcb2b9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -945,13 +945,58 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
*/
unsigned long get_wchan(struct task_struct *p)
{
- unsigned long entry = 0;
+ unsigned long start, bottom, top, sp, fp, ip, ret = 0;
+ int count = 0;
if (p == current || task_is_running(p))
return 0;
- stack_trace_save_tsk(p, &entry, 1, 0);
- return entry;
+ if (!try_get_task_stack(p))
+ return 0;
+
+ start = (unsigned long)task_stack_page(p);
+ if (!start)
+ goto out;
+
+ /*
+ * Layout of the stack page:
+ *
+ * ----------- topmax = start + THREAD_SIZE - sizeof(unsigned long)
+ * PADDING
+ * ----------- top = topmax - TOP_OF_KERNEL_STACK_PADDING
+ * stack
+ * ----------- bottom = start
+ *
+ * The tasks stack pointer points at the location where the
+ * framepointer is stored. The data on the stack is:
+ * ... IP FP ... IP FP
+ *
+ * We need to read FP and IP, so we need to adjust the upper
+ * bound by another unsigned long.
+ */
+ top = start + THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING;
+ top -= 2 * sizeof(unsigned long);
+ bottom = start;
+
+ sp = READ_ONCE(p->thread.sp);
+ if (sp < bottom || sp > top)
+ goto out;
+
+ fp = READ_ONCE_NOCHECK(((struct inactive_task_frame *)sp)->bp);
+ do {
+ if (fp < bottom || fp > top)
+ goto out;
+ ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long)));
+ if (!in_sched_functions(ip)) {
+ ret = ip;
+ goto out;
+ }
+ fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
+ } while (count++ < 16 && !task_is_running(p));
+
+out:
+ put_task_stack(p);
+ return ret;
}
long do_arch_prctl_common(struct task_struct *task, int option,