summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2026-02-16 13:55:30 +0000
committerJens Axboe <axboe@kernel.dk>2026-02-16 08:15:38 -0700
commit2e02f9efdbc6c73544e315b7eb85e55a59776b6f (patch)
tree3151900dcfc0dea594ec115634e6d93183c106a8
parent046fcc83ac1ba8747f0bcae13f5e433802735245 (diff)
io_uring/rsrc: improve regbuf iov validation
Deduplicate io_buffer_validate() calls by moving the checks into io_sqe_buffer_register(). Now we also don't need special handling in io_buffer_validate() passing through buffer removal requests. I also was using it as a cleanup before some other changes. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--io_uring/rsrc.c31
1 files changed, 10 insertions, 21 deletions
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index 05f00bdb02d7..842e231c8a7c 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -96,20 +96,6 @@ int io_validate_user_buf_range(u64 uaddr, u64 ulen)
return 0;
}
-static int io_buffer_validate(struct iovec *iov)
-{
- /*
- * Don't impose further limits on the size and buffer
- * constraints here, we'll -EINVAL later when IO is
- * submitted if they are wrong.
- */
- if (!iov->iov_base)
- return iov->iov_len ? -EFAULT : 0;
-
- return io_validate_user_buf_range((unsigned long)iov->iov_base,
- iov->iov_len);
-}
-
static void io_release_ubuf(void *priv)
{
struct io_mapped_ubuf *imu = priv;
@@ -319,9 +305,6 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
err = -EFAULT;
break;
}
- err = io_buffer_validate(iov);
- if (err)
- break;
node = io_sqe_buffer_register(ctx, iov, &last_hpage);
if (IS_ERR(node)) {
err = PTR_ERR(node);
@@ -790,8 +773,17 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
struct io_imu_folio_data data;
bool coalesced = false;
- if (!iov->iov_base)
+ if (!iov->iov_base) {
+ if (iov->iov_len)
+ return ERR_PTR(-EFAULT);
+ /* remove the buffer without installing a new one */
return NULL;
+ }
+
+ ret = io_validate_user_buf_range((unsigned long)iov->iov_base,
+ iov->iov_len);
+ if (ret)
+ return ERR_PTR(ret);
node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
if (!node)
@@ -897,9 +889,6 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
ret = PTR_ERR(iov);
break;
}
- ret = io_buffer_validate(iov);
- if (ret)
- break;
if (ctx->compat)
arg += sizeof(struct compat_iovec);
else