diff options
| author | Pavel Begunkov <asml.silence@gmail.com> | 2025-11-07 18:41:26 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-11-13 15:37:46 -0500 |
| commit | 826ce37a842633efe1bb763e4b13045d74060d72 (patch) | |
| tree | 87d0df03ec83b0e320f2cb962c8c930ae2cdbfb3 | |
| parent | c43fe1e6d79d971f36e309ba63e0a2a394638c61 (diff) | |
| download | linux-826ce37a842633efe1bb763e4b13045d74060d72.tar.gz linux-826ce37a842633efe1bb763e4b13045d74060d72.tar.bz2 linux-826ce37a842633efe1bb763e4b13045d74060d72.zip | |
io_uring: fix regbuf vector size truncation
commit 146eb58629f45f8297e83d69e64d4eea4b28d972 upstream.
There is a report of io_estimate_bvec_size() truncating the calculated
number of segments that leads to corruption issues. Check it doesn't
overflow "int"s used later. Rough but simple, can be improved on top.
Cc: stable@vger.kernel.org
Fixes: 9ef4cbbcb4ac3 ("io_uring: add infra for importing vectored reg buffers")
Reported-by: Google Big Sleep <big-sleep-vuln-reports+bigsleep-458654612@google.com>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Reviewed-by: Günther Noack <gnoack@google.com>
Tested-by: Günther Noack <gnoack@google.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | io_uring/rsrc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index e1e5f0fb0f56..5961f21dd65d 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1402,8 +1402,11 @@ static int io_estimate_bvec_size(struct iovec *iov, unsigned nr_iovs, size_t max_segs = 0; unsigned i; - for (i = 0; i < nr_iovs; i++) + for (i = 0; i < nr_iovs; i++) { max_segs += (iov[i].iov_len >> shift) + 2; + if (max_segs > INT_MAX) + return -EOVERFLOW; + } return max_segs; } @@ -1509,7 +1512,11 @@ int io_import_reg_vec(int ddir, struct iov_iter *iter, if (unlikely(ret)) return ret; } else { - nr_segs = io_estimate_bvec_size(iov, nr_iovs, imu); + int ret = io_estimate_bvec_size(iov, nr_iovs, imu); + + if (ret < 0) + return ret; + nr_segs = ret; } if (sizeof(struct bio_vec) > sizeof(struct iovec)) { |
