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:
[<
ffffffff8175ea0e>] __asan_report_load8_noabort+0x3e/0x40
[<
ffffffff813e7a26>] sched_show_task+0x306/0x3b0
[<
ffffffff813e7bf4>] show_state_filter+0x124/0x1a0
[<
ffffffff82d2ca00>] fn_show_state+0x10/0x20
[<
ffffffff82d2cf98>] k_spec+0xa8/0xe0
[<
ffffffff82d3354f>] kbd_event+0xb9f/0x4000
[<
ffffffff843ca8a7>] input_to_handler+0x3a7/0x4b0
[<
ffffffff843d1954>] input_pass_values.part.5+0x554/0x6b0
[<
ffffffff843d29bc>] input_handle_event+0x2ac/0x1070
[<
ffffffff843d3a47>] input_inject_event+0x237/0x280
[<
ffffffff843e8c28>] evdev_write+0x478/0x680
[<
ffffffff817ac653>] __vfs_write+0x113/0x480
[<
ffffffff817ae0e7>] vfs_write+0x167/0x4a0
[<
ffffffff817b13d1>] SyS_write+0x111/0x220
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Acked-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
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 <mingo@kernel.org>
* 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);