io_uring: don't re-import iovecs from callbacks
authorPavel Begunkov <asml.silence@gmail.com>
Fri, 3 Jun 2022 12:17:04 +0000 (13:17 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Jun 2022 06:42:41 +0000 (08:42 +0200)
We can't re-import or modify iterators from iocb callbacks, it's not
safe as it might be reverted and/or reexpanded while unwinding stack.
It's also not safe to resubmit as io-wq thread will race with stack
undwinding for the iterator and other data.

Disallow resubmission from callbacks, it can fail some cases that were
handled before, but the possibility of such a failure was a part of the
API from the beginning and so it should be fine.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/io_uring.c

index 3ecf71151fb1fb42dc0b96be418bbae04d7edca3..0b9724c0a2b8077c3a3415c93dfc67c842daf604 100644 (file)
@@ -2579,45 +2579,6 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res,
 #ifdef CONFIG_BLOCK
 static bool io_resubmit_prep(struct io_kiocb *req, int error)
 {
-       struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
-       ssize_t ret = -ECANCELED;
-       struct iov_iter iter;
-       int rw;
-
-       if (error) {
-               ret = error;
-               goto end_req;
-       }
-
-       switch (req->opcode) {
-       case IORING_OP_READV:
-       case IORING_OP_READ_FIXED:
-       case IORING_OP_READ:
-               rw = READ;
-               break;
-       case IORING_OP_WRITEV:
-       case IORING_OP_WRITE_FIXED:
-       case IORING_OP_WRITE:
-               rw = WRITE;
-               break;
-       default:
-               printk_once(KERN_WARNING "io_uring: bad opcode in resubmit %d\n",
-                               req->opcode);
-               goto end_req;
-       }
-
-       if (!req->async_data) {
-               ret = io_import_iovec(rw, req, &iovec, &iter, false);
-               if (ret < 0)
-                       goto end_req;
-               ret = io_setup_async_rw(req, iovec, inline_vecs, &iter, false);
-               if (!ret)
-                       return true;
-               kfree(iovec);
-       } else {
-               return true;
-       }
-end_req:
        req_set_fail_links(req);
        return false;
 }