io_uring: fix read memory leak
authorPavel Begunkov <asml.silence@gmail.com>
Wed, 17 Feb 2021 21:02:36 +0000 (21:02 +0000)
committerJens Axboe <axboe@kernel.dk>
Wed, 17 Feb 2021 21:27:51 +0000 (14:27 -0700)
Don't forget to free iovec read inline completion and bunch of other
cases that do "goto done" before setting up an async context.

Fixes: 5ea5dd45844d ("io_uring: inline io_read()'s iovec freeing")
Reported-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index 58dd104..4352bce 100644 (file)
@@ -3602,10 +3602,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
        ret = io_iter_do_read(req, iter);
 
        if (ret == -EIOCBQUEUED) {
-               /* it's faster to check here then delegate to kfree */
-               if (iovec)
-                       kfree(iovec);
-               return 0;
+               goto out_free;
        } else if (ret == -EAGAIN) {
                /* IOPOLL retry should happen for io-wq threads */
                if (!force_nonblock && !(req->ctx->flags & IORING_SETUP_IOPOLL))
@@ -3626,6 +3623,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
        if (ret2)
                return ret2;
 
+       iovec = NULL;
        rw = req->async_data;
        /* now use our persistent iterator, if we aren't already */
        iter = &rw->iter;
@@ -3652,6 +3650,10 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags)
        } while (ret > 0 && ret < io_size);
 done:
        kiocb_done(kiocb, ret, issue_flags);
+out_free:
+       /* it's faster to check here then delegate to kfree */
+       if (iovec)
+               kfree(iovec);
        return 0;
 }