Skip to content

Commit d6406c4

Browse files
committed
io_uring: track restrictions separately for IORING_OP and IORING_REGISTER
It's quite likely that only register opcode restrictions exists, in which case we'd never need to check the normal opcodes. Split ctx->restricted into two separate fields, one for I/O opcodes, and one for register opcodes. Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 991fb85 commit d6406c4

3 files changed

Lines changed: 22 additions & 9 deletions

File tree

include/linux/io_uring_types.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,10 @@ struct io_restriction {
224224
DECLARE_BITMAP(sqe_op, IORING_OP_LAST);
225225
u8 sqe_flags_allowed;
226226
u8 sqe_flags_required;
227-
bool registered;
227+
/* IORING_OP_* restrictions exist */
228+
bool op_registered;
229+
/* IORING_REGISTER_* restrictions exist */
230+
bool reg_registered;
228231
};
229232

230233
struct io_submit_link {
@@ -259,7 +262,8 @@ struct io_ring_ctx {
259262
struct {
260263
unsigned int flags;
261264
unsigned int drain_next: 1;
262-
unsigned int restricted: 1;
265+
unsigned int op_restricted: 1;
266+
unsigned int reg_restricted: 1;
263267
unsigned int off_timeout_used: 1;
264268
unsigned int drain_active: 1;
265269
unsigned int has_evfd: 1;

io_uring/io_uring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,7 +2056,7 @@ static inline bool io_check_restriction(struct io_ring_ctx *ctx,
20562056
struct io_kiocb *req,
20572057
unsigned int sqe_flags)
20582058
{
2059-
if (!ctx->restricted)
2059+
if (!ctx->op_restricted)
20602060
return true;
20612061
if (!test_bit(req->opcode, ctx->restrictions.sqe_op))
20622062
return false;
@@ -2159,7 +2159,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
21592159
io_init_drain(ctx);
21602160
}
21612161
}
2162-
if (unlikely(ctx->restricted || ctx->drain_active || ctx->drain_next)) {
2162+
if (unlikely(ctx->op_restricted || ctx->drain_active || ctx->drain_next)) {
21632163
if (!io_check_restriction(ctx, req, sqe_flags))
21642164
return io_init_fail_req(req, -EACCES);
21652165
/* knock it to the slow queue path, will be drained there */

io_uring/register.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,24 +133,31 @@ static __cold int io_parse_restrictions(void __user *arg, unsigned int nr_args,
133133
if (res[i].register_op >= IORING_REGISTER_LAST)
134134
goto err;
135135
__set_bit(res[i].register_op, restrictions->register_op);
136+
restrictions->reg_registered = true;
136137
break;
137138
case IORING_RESTRICTION_SQE_OP:
138139
if (res[i].sqe_op >= IORING_OP_LAST)
139140
goto err;
140141
__set_bit(res[i].sqe_op, restrictions->sqe_op);
142+
restrictions->op_registered = true;
141143
break;
142144
case IORING_RESTRICTION_SQE_FLAGS_ALLOWED:
143145
restrictions->sqe_flags_allowed = res[i].sqe_flags;
146+
restrictions->op_registered = true;
144147
break;
145148
case IORING_RESTRICTION_SQE_FLAGS_REQUIRED:
146149
restrictions->sqe_flags_required = res[i].sqe_flags;
150+
restrictions->op_registered = true;
147151
break;
148152
default:
149153
goto err;
150154
}
151155
}
152156
ret = nr_args;
153-
restrictions->registered = true;
157+
if (!nr_args) {
158+
restrictions->op_registered = true;
159+
restrictions->reg_registered = true;
160+
}
154161
err:
155162
kfree(res);
156163
return ret;
@@ -166,7 +173,7 @@ static __cold int io_register_restrictions(struct io_ring_ctx *ctx,
166173
return -EBADFD;
167174

168175
/* We allow only a single restrictions registration */
169-
if (ctx->restrictions.registered)
176+
if (ctx->restrictions.op_registered || ctx->restrictions.reg_registered)
170177
return -EBUSY;
171178

172179
ret = io_parse_restrictions(arg, nr_args, &ctx->restrictions);
@@ -175,8 +182,10 @@ static __cold int io_register_restrictions(struct io_ring_ctx *ctx,
175182
memset(&ctx->restrictions, 0, sizeof(ctx->restrictions));
176183
return ret;
177184
}
178-
if (ctx->restrictions.registered)
179-
ctx->restricted = 1;
185+
if (ctx->restrictions.op_registered)
186+
ctx->op_restricted = 1;
187+
if (ctx->restrictions.reg_registered)
188+
ctx->reg_restricted = 1;
180189
return 0;
181190
}
182191

@@ -626,7 +635,7 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
626635
if (ctx->submitter_task && ctx->submitter_task != current)
627636
return -EEXIST;
628637

629-
if (ctx->restricted && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
638+
if (ctx->reg_restricted && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
630639
opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
631640
if (!test_bit(opcode, ctx->restrictions.register_op))
632641
return -EACCES;

0 commit comments

Comments
 (0)