diff options
author | 2021-04-15 13:07:40 +0100 | |
---|---|---|
committer | 2021-04-17 19:20:08 -0600 | |
commit | 75c4021aacbd9b5cc13b173d32b49007fd8ccada (patch) | |
tree | 7575ca680cb37fc4a9c503ce635422c691228298 /fs/io_uring.c | |
parent | io_uring: fix overflows checks in provide buffers (diff) | |
download | linux-75c4021aacbd9b5cc13b173d32b49007fd8ccada.tar.gz linux-75c4021aacbd9b5cc13b173d32b49007fd8ccada.tar.bz2 linux-75c4021aacbd9b5cc13b173d32b49007fd8ccada.zip |
io_uring: check register restriction afore quiesce
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>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index bae13811d2f3..e491b815df8c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -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); |