6.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
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 --- io_uring/rsrc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1402,8 +1402,11 @@ static int io_estimate_bvec_size(struct 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 i 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)) {