On Mon, Mar 04, 2024 at 10:29:44AM -0800, Bart Van Assche wrote: > Patch "fs/aio: Make io_cancel() generate completions again" is based on the > assumption that calling kiocb->ki_cancel() does not complete R/W requests. > This is incorrect: the two drivers that call kiocb_set_cancel_fn() callers > set a cancellation function that calls usb_ep_dequeue(). According to its > documentation, usb_ep_dequeue() calls the completion routine with status > -ECONNRESET. Hence this revert. > > Cc: Benjamin LaHaise <ben@xxxxxxxxxxxxxxxxx> > Cc: Eric Biggers <ebiggers@xxxxxxxxxx> > Cc: Christoph Hellwig <hch@xxxxxx> > Cc: Avi Kivity <avi@xxxxxxxxxxxx> > Cc: Sandeep Dhavale <dhavale@xxxxxxxxxx> > Cc: Jens Axboe <axboe@xxxxxxxxx> > Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > Cc: Kent Overstreet <kent.overstreet@xxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Reported-by: syzbot+b91eb2ed18f599dd3c31@xxxxxxxxxxxxxxxxxxxxxxxxx > Fixes: 54cbc058d86b ("fs/aio: Make io_cancel() generate completions again") > Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> > --- > fs/aio.c | 27 ++++++++++++++++----------- > 1 file changed, 16 insertions(+), 11 deletions(-) > > diff --git a/fs/aio.c b/fs/aio.c > index 28223f511931..da18dbcfcb22 100644 > --- a/fs/aio.c > +++ b/fs/aio.c > @@ -2165,11 +2165,14 @@ COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, > #endif > > /* sys_io_cancel: > - * Attempts to cancel an iocb previously passed to io_submit(). If the > - * operation is successfully cancelled 0 is returned. May fail with > - * -EFAULT if any of the data structures pointed to are invalid. May > - * fail with -EINVAL if aio_context specified by ctx_id is invalid. Will > - * fail with -ENOSYS if not implemented. > + * Attempts to cancel an iocb previously passed to io_submit. If > + * the operation is successfully cancelled, the resulting event is > + * copied into the memory pointed to by result without being placed > + * into the completion queue and 0 is returned. May fail with > + * -EFAULT if any of the data structures pointed to are invalid. > + * May fail with -EINVAL if aio_context specified by ctx_id is > + * invalid. May fail with -EAGAIN if the iocb specified was not > + * cancelled. Will fail with -ENOSYS if not implemented. > */ > SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, > struct io_event __user *, result) > @@ -2200,12 +2203,14 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, > } > spin_unlock_irq(&ctx->ctx_lock); > > - /* > - * The result argument is no longer used - the io_event is always > - * delivered via the ring buffer. > - */ > - if (ret == 0 && kiocb->rw.ki_flags & IOCB_AIO_RW) > - aio_complete_rw(&kiocb->rw, -EINTR); > + if (!ret) { > + /* > + * The result argument is no longer used - the io_event is > + * always delivered via the ring buffer. -EINPROGRESS indicates > + * cancellation is progress: > + */ > + ret = -EINPROGRESS; > + } Acked-by: Eric Biggers <ebiggers@xxxxxxxxxx> It does look like all the ->ki_cancel functions complete the request already, so this patch was unnecessary and just introduced a bug. Note that IOCB_CMD_POLL installs a ->ki_cancel function too, and that's how syzbot hit the use-after-free so easily. I assume that the patch just wasn't tested? Or did you find that it actually fixed something (how)? By the way, libaio (https://pagure.io/libaio) has a test suite for these system calls. How about adding a test case that cancels an IOCB_CMD_POLL request and verifies that the completion event is received? - Eric