]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
io_uring/rsrc: clean up buffer cloning arg validation
authorJoanne Koong <joannelkoong@gmail.com>
Thu, 4 Dec 2025 21:51:14 +0000 (13:51 -0800)
committerJens Axboe <axboe@kernel.dk>
Thu, 4 Dec 2025 22:46:13 +0000 (15:46 -0700)
Get rid of some redundant checks and move the src arg validation to
before the buffer table allocation, which simplifies error handling.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/rsrc.c

index 3765a50329a8c523af40a2fd0e66f291c81b9260..5ad3d10413eb538a29084f4c8011660e9afe69fa 100644 (file)
@@ -1186,12 +1186,16 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
                return -EBUSY;
 
        nbufs = src_ctx->buf_table.nr;
+       if (!nbufs)
+               return -ENXIO;
        if (!arg->nr)
                arg->nr = nbufs;
        else if (arg->nr > nbufs)
                return -EINVAL;
        else if (arg->nr > IORING_MAX_REG_BUFFERS)
                return -EINVAL;
+       if (check_add_overflow(arg->nr, arg->src_off, &off) || off > nbufs)
+               return -EOVERFLOW;
        if (check_add_overflow(arg->nr, arg->dst_off, &nbufs))
                return -EOVERFLOW;
        if (nbufs > IORING_MAX_REG_BUFFERS)
@@ -1211,21 +1215,6 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
                }
        }
 
-       ret = -ENXIO;
-       nbufs = src_ctx->buf_table.nr;
-       if (!nbufs)
-               goto out_free;
-       ret = -EINVAL;
-       if (!arg->nr)
-               arg->nr = nbufs;
-       else if (arg->nr > nbufs)
-               goto out_free;
-       ret = -EOVERFLOW;
-       if (check_add_overflow(arg->nr, arg->src_off, &off))
-               goto out_free;
-       if (off > nbufs)
-               goto out_free;
-
        off = arg->dst_off;
        i = arg->src_off;
        nr = arg->nr;
@@ -1238,8 +1227,8 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
                } else {
                        dst_node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
                        if (!dst_node) {
-                               ret = -ENOMEM;
-                               goto out_free;
+                               io_rsrc_data_free(ctx, &data);
+                               return -ENOMEM;
                        }
 
                        refcount_inc(&src_node->buf->refs);
@@ -1265,10 +1254,6 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
        WARN_ON_ONCE(ctx->buf_table.nr);
        ctx->buf_table = data;
        return 0;
-
-out_free:
-       io_rsrc_data_free(ctx, &data);
-       return ret;
 }
 
 /*