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>
This commit is contained in:
Pavel Begunkov 2026-02-16 13:55:30 +00:00 committed by Jens Axboe
parent 046fcc83ac
commit 2e02f9efdb

View file

@ -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