On 25/11/2020 02:19, Pavel Begunkov wrote: > io_uring_cancel_files()'s task check condition mistakenly got flipped. > > 1. There can't be a request in the inflight list without > IO_WQ_WORK_FILES, kill this check to keep the whole condition simpler. > 2. Also, don't call the function for files==NULL to not do such a check, > all that staff is already handled well by its counter part, > __io_uring_cancel_task_requests(). > > With that just flip the task check. > > Also, it iowq-cancels all request of current task there, don't forget to > set right ->files into struct io_task_cancel.> > Reported-by: syzbot+c0d52d0b3c0c3ffb9525@xxxxxxxxxxxxxxxxxxxxxxxxx So, I screwed it just recently and for-5.11. Thanks to syzkaller for catching this early. Just to notice that the reproducer segfaults for me, so I haven't really reproduced it and needs "syz test" to confirm > Fixes: c1973b38bf639 ("io_uring: cancel only requests of current task") > Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> > --- > fs/io_uring.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/fs/io_uring.c b/fs/io_uring.c > index 7c1f255807f5..f11dc25d975c 100644 > --- a/fs/io_uring.c > +++ b/fs/io_uring.c > @@ -8725,15 +8725,14 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, > struct files_struct *files) > { > while (!list_empty_careful(&ctx->inflight_list)) { > - struct io_task_cancel cancel = { .task = task, .files = NULL, }; > + struct io_task_cancel cancel = { .task = task, .files = files }; > struct io_kiocb *req; > DEFINE_WAIT(wait); > bool found = false; > > spin_lock_irq(&ctx->inflight_lock); > list_for_each_entry(req, &ctx->inflight_list, inflight_entry) { > - if (req->task == task && > - (req->work.flags & IO_WQ_WORK_FILES) && > + if (req->task != task || > req->work.identity->files != files) > continue; > found = true; > @@ -8805,10 +8804,11 @@ static void io_uring_cancel_task_requests(struct io_ring_ctx *ctx, > > io_cancel_defer_files(ctx, task, files); > io_cqring_overflow_flush(ctx, true, task, files); > - io_uring_cancel_files(ctx, task, files); > > if (!files) > __io_uring_cancel_task_requests(ctx, task); > + else > + io_uring_cancel_files(ctx, task, files); > > if ((ctx->flags & IORING_SETUP_SQPOLL) && ctx->sq_data) { > atomic_dec(&task->io_uring->in_idle); > -- Pavel Begunkov