]> git.hungrycats.org Git - linux/commitdiff
io_uring/rsrc: improve regbuf iov validation
authorPavel Begunkov <asml.silence@gmail.com>
Tue, 25 Aug 2026 19:47:43 +0000 (15:47 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Sep 2026 12:31:47 +0000 (14:31 +0200)
[ Upstream commit 2e02f9efdbc6c73544e315b7eb85e55a59776b6f ]

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>
Stable-dep-of: cd305ee3633a ("io_uring: defer eventfd signaling when queued from a wakeup handler")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
io_uring/rsrc.c

index b6a070abbf9973da3ea80c6cd97a70b561394d06..8d28c6bfebb1ecb04afa3e224482036c04e5b474 100644 (file)
@@ -94,20 +94,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;
@@ -317,9 +303,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);
@@ -788,8 +771,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)
@@ -895,9 +887,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