lkml.org 
[lkml]   [2019]   [Apr]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH] io_uring: fix SQPOLL cpu validation
From
Date
On 4/30/19 6:34 AM, Mark Rutland wrote:
> In io_sq_offload_start(), we call cpu_possible() on an unbounded cpu
> value from userspace. On v5.1-rc7 on arm64 with
> CONFIG_DEBUG_PER_CPU_MAPS, this results in a splat:
>
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 cpu_max_bits_warn include/linux/cpumask.h:121 [inline]
>
> There was an attempt to fix this in commit:
>
> 917257daa0fea7a0 ("io_uring: only test SQPOLL cpu after we've verified it")
>
> ... by adding a check after the cpu value had been limited to NR_CPU_IDS
> using array_index_nospec(). However, this left an unbound check at the
> start of the function, for which the warning still fires.
>
> Let's fix this correctly by checking that the cpu value is bound by
> nr_cpu_ids before passing it to cpu_possible(). Note that only
> nr_cpu_ids of a cpumask are guaranteed to exist at runtime, and
> nr_cpu_ids can be significantly smaller than NR_CPUs. For example, an
> arm64 defconfig has NR_CPUS=256, while my test VM has 4 vCPUs.
>
> Following the intent from the commit message for 917257daa0fea7a0, the
> check is moved under the SQ_AFF branch, which is the only branch where
> the cpu values is consumed. The check is performed before bounding the
> value with array_index_nospec() so that we don't silently accept bogus
> cpu values from userspace, where array_index_nospec() would force these
> values to 0.
>
> I suspect we can remove the array_index_nospec() call entirely, but I've
> conservatively left that in place, updated to use nr_cpu_ids to match
> the prior check.
>
> Tested on arm64 with the Syzkaller reproducer:
>
> https://syzkaller.appspot.com/bug?extid=cd714a07c6de2bc34293
> https://syzkaller.appspot.com/x/repro.syz?x=15d8b397200000
>
> Full splat from before this patch:
>
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 cpu_max_bits_warn include/linux/cpumask.h:121 [inline]
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 cpumask_check include/linux/cpumask.h:128 [inline]
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 cpumask_test_cpu include/linux/cpumask.h:344 [inline]
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 io_sq_offload_start fs/io_uring.c:2244 [inline]
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 io_uring_create fs/io_uring.c:2864 [inline]
> WARNING: CPU: 1 PID: 27601 at include/linux/cpumask.h:121 io_uring_setup+0x1108/0x15a0 fs/io_uring.c:2916
> Kernel panic - not syncing: panic_on_warn set ...
> CPU: 1 PID: 27601 Comm: syz-executor.0 Not tainted 5.1.0-rc7 #3
> Hardware name: linux,dummy-virt (DT)
> Call trace:
> dump_backtrace+0x0/0x2f0 include/linux/compiler.h:193
> show_stack+0x20/0x30 arch/arm64/kernel/traps.c:158
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0x110/0x190 lib/dump_stack.c:113
> panic+0x384/0x68c kernel/panic.c:214
> __warn+0x2bc/0x2c0 kernel/panic.c:571
> report_bug+0x228/0x2d8 lib/bug.c:186
> bug_handler+0xa0/0x1a0 arch/arm64/kernel/traps.c:956
> call_break_hook arch/arm64/kernel/debug-monitors.c:301 [inline]
> brk_handler+0x1d4/0x388 arch/arm64/kernel/debug-monitors.c:316
> do_debug_exception+0x1a0/0x468 arch/arm64/mm/fault.c:831
> el1_dbg+0x18/0x8c
> cpu_max_bits_warn include/linux/cpumask.h:121 [inline]
> cpumask_check include/linux/cpumask.h:128 [inline]
> cpumask_test_cpu include/linux/cpumask.h:344 [inline]
> io_sq_offload_start fs/io_uring.c:2244 [inline]
> io_uring_create fs/io_uring.c:2864 [inline]
> io_uring_setup+0x1108/0x15a0 fs/io_uring.c:2916
> __do_sys_io_uring_setup fs/io_uring.c:2929 [inline]
> __se_sys_io_uring_setup fs/io_uring.c:2926 [inline]
> __arm64_sys_io_uring_setup+0x50/0x70 fs/io_uring.c:2926
> __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
> invoke_syscall arch/arm64/kernel/syscall.c:47 [inline]
> el0_svc_common.constprop.0+0x148/0x2e0 arch/arm64/kernel/syscall.c:83
> el0_svc_handler+0xdc/0x100 arch/arm64/kernel/syscall.c:129
> el0_svc+0x8/0xc arch/arm64/kernel/entry.S:948
> SMP: stopping secondary CPUs
> Dumping ftrace buffer:
> (ftrace buffer empty)
> Kernel Offset: disabled
> CPU features: 0x002,23000438
> Memory Limit: none
> Rebooting in 1 seconds..

Applied, thanks.

--
Jens Axboe

\
 
 \ /
  Last update: 2019-04-30 18:21    [W:0.062 / U:0.400 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site