| From 5d204bcfa09330972ad3428a8f81c23f371d3e6d Mon Sep 17 00:00:00 2001 |
| From: Jens Axboe <axboe@kernel.dk> |
| Date: Fri, 31 Jan 2020 12:06:52 -0700 |
| Subject: io_uring: don't map read/write iovec potentially twice |
| |
| From: Jens Axboe <axboe@kernel.dk> |
| |
| commit 5d204bcfa09330972ad3428a8f81c23f371d3e6d upstream. |
| |
| If we have a read/write that is deferred, we already setup the async IO |
| context for that request, and mapped it. When we later try and execute |
| the request and we get -EAGAIN, we don't want to attempt to re-map it. |
| If we do, we end up with garbage in the iovec, which typically leads |
| to an -EFAULT or -EINVAL completion. |
| |
| Cc: stable@vger.kernel.org # 5.5 |
| Reported-by: Dan Melnic <dmm@fb.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/io_uring.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| --- a/fs/io_uring.c |
| +++ b/fs/io_uring.c |
| @@ -1789,10 +1789,12 @@ static int io_setup_async_rw(struct io_k |
| if (req->opcode == IORING_OP_READ_FIXED || |
| req->opcode == IORING_OP_WRITE_FIXED) |
| return 0; |
| - if (!req->io && io_alloc_async_ctx(req)) |
| - return -ENOMEM; |
| + if (!req->io) { |
| + if (io_alloc_async_ctx(req)) |
| + return -ENOMEM; |
| |
| - io_req_map_rw(req, io_size, iovec, fast_iov, iter); |
| + io_req_map_rw(req, io_size, iovec, fast_iov, iter); |
| + } |
| req->work.func = io_rw_async; |
| return 0; |
| } |