On Fri, Mar 30, 2018 at 05:07:45PM +0200, Christoph Hellwig wrote:
> The current kiocb_set_cancel_fn implementation assumes the kiocb is
> embedded into an aio_kiocb, which is fundamentally unsafe as it might
> have been submitted by non-aio callers.  Instead add a cancel_kiocb
> file operation that replaced the ki_cancel function pointer set by
> kiocb_set_cancel_fn, and only adds iocbs to the active list when
> the read/write_iter methods return -EIOCBQUEUED and the file has
> a cancel_kiocb method.

> @@ -1440,6 +1423,16 @@ static inline ssize_t aio_rw_ret(struct kiocb *req, 
> ssize_t ret)
>  {
>       switch (ret) {
>       case -EIOCBQUEUED:
> +             if (req->ki_filp->f_op->cancel_kiocb) {

... and by that point req might've been already freed by IO completion on
another CPU.
> +                     struct aio_kiocb *iocb =
> +                             container_of(req, struct aio_kiocb, rw);
> +                     struct kioctx *ctx = iocb->ki_ctx;
> +                     unsigned long flags;
> +
> +                     spin_lock_irqsave(&ctx->ctx_lock, flags);
> +                     list_add_tail(&iocb->ki_list, &ctx->active_reqs);

Reply via email to