From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 0dc636b3b757a6b747a156de613275f9d74a4a66 ]
When commit 5d1ceb3969b6 ("x86: Fix __get_wchan() for !STACKTRACE") moved from stacktrace to native unwind_*() usage, the try_get_task_stack() got lost, leading to use-after-free issues for dying tasks.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Fixes: 5d1ceb3969b6 ("x86: Fix __get_wchan() for !STACKTRACE") Link: https://bugzilla.kernel.org/show_bug.cgi?id=215031 Link: https://lore.kernel.org/stable/YZV02RCRVHIa144u@fedora64.linuxtx.org/ Reported-by: Justin Forbes jmforbes@linuxtx.org Reported-by: Holger Hoffstätte holger@applied-asynchrony.com Cc: Qi Zheng zhengqi.arch@bytedance.com Cc: Kees Cook keescook@chromium.org Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Siddhi Katage siddhi.katage@oracle.com --- arch/x86/kernel/process.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 16d4c5a79d68..2a4218deddd2 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -975,6 +975,9 @@ unsigned long __get_wchan(struct task_struct *p) struct unwind_state state; unsigned long addr = 0;
+ if (!try_get_task_stack(p)) + return 0; + for (unwind_start(&state, p, NULL, NULL); !unwind_done(&state); unwind_next_frame(&state)) { addr = unwind_get_return_address(&state); @@ -985,6 +988,8 @@ unsigned long __get_wchan(struct task_struct *p) break; }
+ put_task_stack(p); + return addr; }