]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
io_uring/rsrc: improve regbuf iov validation
authorPavel Begunkov <asml.silence@gmail.com>
Mon, 16 Feb 2026 13:55:30 +0000 (13:55 +0000)
committerJens Axboe <axboe@kernel.dk>
Mon, 16 Feb 2026 15:15:38 +0000 (08:15 -0700)
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>
io_uring/rsrc.c

index 05f00bdb02d7cdde8bac6f5f27a601438ce0dc3d..842e231c8a7c41262942f6c2087b35ee2863c60a 100644 (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