DECLARE_BITMAP(sqe_op, IORING_OP_LAST);
u8 sqe_flags_allowed;
u8 sqe_flags_required;
- bool registered;
+ /* IORING_OP_* restrictions exist */
+ bool op_registered;
+ /* IORING_REGISTER_* restrictions exist */
+ bool reg_registered;
};
struct io_submit_link {
struct {
unsigned int flags;
unsigned int drain_next: 1;
- unsigned int restricted: 1;
+ unsigned int op_restricted: 1;
+ unsigned int reg_restricted: 1;
unsigned int off_timeout_used: 1;
unsigned int drain_active: 1;
unsigned int has_evfd: 1;
struct io_kiocb *req,
unsigned int sqe_flags)
{
- if (!ctx->restricted)
+ if (!ctx->op_restricted)
return true;
if (!test_bit(req->opcode, ctx->restrictions.sqe_op))
return false;
io_init_drain(ctx);
}
}
- if (unlikely(ctx->restricted || ctx->drain_active || ctx->drain_next)) {
+ if (unlikely(ctx->op_restricted || ctx->drain_active || ctx->drain_next)) {
if (!io_check_restriction(ctx, req, sqe_flags))
return io_init_fail_req(req, -EACCES);
/* knock it to the slow queue path, will be drained there */
if (res[i].register_op >= IORING_REGISTER_LAST)
goto err;
__set_bit(res[i].register_op, restrictions->register_op);
+ restrictions->reg_registered = true;
break;
case IORING_RESTRICTION_SQE_OP:
if (res[i].sqe_op >= IORING_OP_LAST)
goto err;
__set_bit(res[i].sqe_op, restrictions->sqe_op);
+ restrictions->op_registered = true;
break;
case IORING_RESTRICTION_SQE_FLAGS_ALLOWED:
restrictions->sqe_flags_allowed = res[i].sqe_flags;
+ restrictions->op_registered = true;
break;
case IORING_RESTRICTION_SQE_FLAGS_REQUIRED:
restrictions->sqe_flags_required = res[i].sqe_flags;
+ restrictions->op_registered = true;
break;
default:
goto err;
}
}
ret = nr_args;
- restrictions->registered = true;
+ if (!nr_args) {
+ restrictions->op_registered = true;
+ restrictions->reg_registered = true;
+ }
err:
kfree(res);
return ret;
return -EBADFD;
/* We allow only a single restrictions registration */
- if (ctx->restrictions.registered)
+ if (ctx->restrictions.op_registered || ctx->restrictions.reg_registered)
return -EBUSY;
ret = io_parse_restrictions(arg, nr_args, &ctx->restrictions);
memset(&ctx->restrictions, 0, sizeof(ctx->restrictions));
return ret;
}
- if (ctx->restrictions.registered)
- ctx->restricted = 1;
+ if (ctx->restrictions.op_registered)
+ ctx->op_restricted = 1;
+ if (ctx->restrictions.reg_registered)
+ ctx->reg_restricted = 1;
return 0;
}
if (ctx->submitter_task && ctx->submitter_task != current)
return -EEXIST;
- if (ctx->restricted && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
+ if (ctx->reg_restricted && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
if (!test_bit(opcode, ctx->restrictions.register_op))
return -EACCES;