]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Feb 2026 22:59:47 +0000 (14:59 -0800)
commit b8201b50e403815f941d1c6581a27fdbfe7d0fd4 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
io_uring/rsrc.c

index 160b4de2d00d3c3d6c6ee7f5f0d39b742d392d26..44442bf4827e473a47b25c39ebde715e8e0b52b9 100644 (file)
@@ -1185,12 +1185,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)
@@ -1210,21 +1214,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;
@@ -1237,8 +1226,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);
@@ -1274,10 +1263,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;
 }
 
 /*