Skip to content

Commit

Permalink
Revert "x86: Fix get_wchan() to support the ORC unwinder"
Browse files Browse the repository at this point in the history
This reverts commit f270511 which is
commit bc9bbb8 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>
  • Loading branch information
Greg Kroah-Hartman committed Nov 18, 2021
1 parent 961913f commit 1b86960
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions arch/x86/kernel/process.c
Original file line number Diff line number Diff line change
@@ -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,

0 comments on commit 1b86960

Please sign in to comment.