io_uring: check register restriction afore quiesce
authorPavel Begunkov <asml.silence@gmail.com>
Thu, 15 Apr 2021 12:07:40 +0000 (13:07 +0100)
committerJens Axboe <axboe@kernel.dk>
Sun, 18 Apr 2021 01:20:08 +0000 (19:20 -0600)
Move restriction checks of __io_uring_register() before quiesce, saves
from waiting for requests in fail case and simplifies the code a bit.
Also add array_index_nospec() for safety

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/88d7913c9280ee848fdb7b584eea37a465391cee.1618488258.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index bae13811d2f39245955bdd5a18e887575218b0aa..e491b815df8c02d2c91ceaacf132a84ca38d680d 100644 (file)
@@ -9738,6 +9738,14 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
        if (percpu_ref_is_dying(&ctx->refs))
                return -ENXIO;
 
+       if (ctx->restricted) {
+               if (opcode >= IORING_REGISTER_LAST)
+                       return -EINVAL;
+               opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
+               if (!test_bit(opcode, ctx->restrictions.register_op))
+                       return -EACCES;
+       }
+
        if (io_register_op_must_quiesce(opcode)) {
                percpu_ref_kill(&ctx->refs);
 
@@ -9766,18 +9774,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
                }
        }
 
-       if (ctx->restricted) {
-               if (opcode >= IORING_REGISTER_LAST) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-
-               if (!test_bit(opcode, ctx->restrictions.register_op)) {
-                       ret = -EACCES;
-                       goto out;
-               }
-       }
-
        switch (opcode) {
        case IORING_REGISTER_BUFFERS:
                ret = io_sqe_buffers_register(ctx, arg, nr_args);
@@ -9851,7 +9847,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
                break;
        }
 
-out:
        if (io_register_op_must_quiesce(opcode)) {
                /* bring the ctx back to life */
                percpu_ref_reinit(&ctx->refs);