From 75edb54a1dea5ea1c8d3d82e27dc9ee3070f5935 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 4 Feb 2016 16:27:50 +0100 Subject: [PATCH] x86: Fix KASAN false positives in thread_saved_pc() thread_saved_pc() reads stack of a potentially running task. This can cause false KASAN stack-out-of-bounds reports, because the running task concurrently poisons and unpoisons own stack. The same happens in get_wchan(), and get get_wchan() was fixed by using READ_ONCE_NOCHECK(). Do the same here. Example KASAN report triggered by sysrq-t: BUG: KASAN: out-of-bounds in sched_show_task+0x306/0x3b0 at addr ffff880043c97c18 Read of size 8 by task syz-executor/23839 [...] page dumped because: kasan: bad access detected [...] Call Trace: [] __asan_report_load8_noabort+0x3e/0x40 [] sched_show_task+0x306/0x3b0 [] show_state_filter+0x124/0x1a0 [] fn_show_state+0x10/0x20 [] k_spec+0xa8/0xe0 [] kbd_event+0xb9f/0x4000 [] input_to_handler+0x3a7/0x4b0 [] input_pass_values.part.5+0x554/0x6b0 [] input_handle_event+0x2ac/0x1070 [] input_inject_event+0x237/0x280 [] evdev_write+0x478/0x680 [] __vfs_write+0x113/0x480 [] vfs_write+0x167/0x4a0 [] SyS_write+0x111/0x220 Signed-off-by: Dmitry Vyukov Acked-by: Andrey Ryabinin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: glider@google.com Cc: kasan-dev@googlegroups.com Cc: kcc@google.com Cc: linux-kernel@vger.kernel.org Cc: ryabinin.a.a@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 2d5a50cb61a2..20c11d1aa4cc 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -766,7 +766,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. */ -#define thread_saved_pc(t) (*(unsigned long *)((t)->thread.sp - 8)) +#define thread_saved_pc(t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8)) #define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1) extern unsigned long KSTK_ESP(struct task_struct *task); -- 2.30.2