Skip to content

Commit 89c2b3b

Browse files
isilenceAl Viro
authored andcommitted
io_uring: reexpand under-reexpanded iters
[ 74.211232] BUG: KASAN: stack-out-of-bounds in iov_iter_revert+0x809/0x900 [ 74.212778] Read of size 8 at addr ffff888025dc78b8 by task syz-executor.0/828 [ 74.214756] CPU: 0 PID: 828 Comm: syz-executor.0 Not tainted 5.14.0-rc3-next-20210730 Rust-for-Linux#1 [ 74.216525] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [ 74.219033] Call Trace: [ 74.219683] dump_stack_lvl+0x8b/0xb3 [ 74.220706] print_address_description.constprop.0+0x1f/0x140 [ 74.224226] kasan_report.cold+0x7f/0x11b [ 74.226085] iov_iter_revert+0x809/0x900 [ 74.227960] io_write+0x57d/0xe40 [ 74.232647] io_issue_sqe+0x4da/0x6a80 [ 74.242578] __io_queue_sqe+0x1ac/0xe60 [ 74.245358] io_submit_sqes+0x3f6e/0x76a0 [ 74.248207] __do_sys_io_uring_enter+0x90c/0x1a20 [ 74.257167] do_syscall_64+0x3b/0x90 [ 74.257984] entry_SYSCALL_64_after_hwframe+0x44/0xae old_size = iov_iter_count(); ... iov_iter_revert(old_size - iov_iter_count()); If iov_iter_revert() is done base on the initial size as above, and the iter is truncated and not reexpanded in the middle, it miscalculates borders causing problems. This trace is due to no one reexpanding after generic_write_checks(). Now iters store how many bytes has been truncated, so reexpand them to the initial state right before reverting. Cc: stable@vger.kernel.org Reported-by: Palash Oswal <oswalpalash@gmail.com> Reported-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Reported-and-tested-by: syzbot+9671693590ef5aad8953@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 2112ff5 commit 89c2b3b

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

fs/io_uring.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3281,6 +3281,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
32813281
if (req->flags & REQ_F_NOWAIT)
32823282
goto done;
32833283
/* some cases will consume bytes even on error returns */
3284+
iov_iter_reexpand(iter, iter->count + iter->truncated);
32843285
iov_iter_revert(iter, io_size - iov_iter_count(iter));
32853286
ret = 0;
32863287
} else if (ret == -EIOCBQUEUED) {
@@ -3420,6 +3421,7 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags)
34203421
} else {
34213422
copy_iov:
34223423
/* some cases will consume bytes even on error returns */
3424+
iov_iter_reexpand(iter, iter->count + iter->truncated);
34233425
iov_iter_revert(iter, io_size - iov_iter_count(iter));
34243426
ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
34253427
return ret ?: -EAGAIN;

0 commit comments

Comments
 (0)