From 75edb54a1dea5ea1c8d3d82e27dc9ee3070f5935 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 4 Feb 2016 16:27:50 +0100 Subject: 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); -- cgit v1.2.3-70-g09d2 From 59fd1214561921343305a0e9dc218bf3d40068f3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 8 Feb 2016 08:47:48 +0100 Subject: x86/mm/numa: Fix 32-bit memblock range truncation bug on 32-bit NUMA kernels The following commit: a0acda917284 ("acpi, numa, mem_hotplug: mark all nodes the kernel resides un-hotpluggable") Introduced numa_clear_kernel_node_hotplug(), which function is executed during early bootup, and which marks all currently reserved memblock regions as hot-memory-unswappable as well. y14sg1 reported that when running 32-bit NUMA kernels, the grsecurity/PAX kernel patch flagged a size overflow in this function: PAX: size overflow detected in function x86_numa_init arch/x86/mm/numa.c:691 [...] ... the reason for the overflow is that memblock_clear_hotplug() takes physical addresses as arguments, while the start/end variables used by numa_clear_kernel_node_hotplug() are 'unsigned long', which is 32-bit on PAE kernels, but which has 64-bit physical addresses. So on 32-bit PAE kernels that have physical memory above the 4GB boundary, we truncate a 64-bit physical address range to 32 bits and pass it to memblock_clear_hotplug(), which at minimum prevents the original memory-hotplug bugfix from working, but might have other side effects as well. The fix is to use the proper type to handle physical addresses, phys_addr_t. Reported-by: y14sg1 Cc: Andrew Morton Cc: Brad Spengler Cc: Chen Tang Cc: "H. Peter Anvin" Cc: Lai Jiangshan Cc: Linus Torvalds Cc: PaX Team Cc: Taku Izumi Cc: Tang Chen Cc: Thomas Gleixner Cc: Wen Congyang Cc: Yasuaki Ishimatsu Cc: Zhang Yanfei Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/mm/numa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index c3b3f653ed0c..d04f8094bc23 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -469,7 +469,7 @@ static void __init numa_clear_kernel_node_hotplug(void) { int i, nid; nodemask_t numa_kernel_nodes = NODE_MASK_NONE; - unsigned long start, end; + phys_addr_t start, end; struct memblock_region *r; /* -- cgit v1.2.3-70-g09d2