Commit 7a8737e1 authored by Caleb Sander Mateos's avatar Caleb Sander Mateos Committed by Jens Axboe
Browse files

io_uring: use release-acquire ordering for IORING_SETUP_R_DISABLED



io_uring_enter(), __io_msg_ring_data(), and io_msg_send_fd() read
ctx->flags and ctx->submitter_task without holding the ctx's uring_lock.
This means they may race with the assignment to ctx->submitter_task and
the clearing of IORING_SETUP_R_DISABLED from ctx->flags in
io_register_enable_rings(). Ensure the correct ordering of the
ctx->flags and ctx->submitter_task memory accesses by storing to
ctx->flags using release ordering and loading it using acquire ordering.

Signed-off-by: default avatarCaleb Sander Mateos <csander@purestorage.com>
Fixes: 4add705e ("io_uring: remove io_register_submitter")
Reviewed-by: default avatarJoanne Koong <joannelkoong@gmail.com>
Reviewed-by: default avatarGabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 48ed7013
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -3228,7 +3228,11 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,

	ctx = file->private_data;
	ret = -EBADFD;
	if (unlikely(ctx->flags & IORING_SETUP_R_DISABLED))
	/*
	 * Keep IORING_SETUP_R_DISABLED check before submitter_task load
	 * in io_uring_add_tctx_node() -> __io_uring_add_tctx_node_from_submit()
	 */
	if (unlikely(smp_load_acquire(&ctx->flags) & IORING_SETUP_R_DISABLED))
		goto out;

	/*
+10 −2
Original line number Diff line number Diff line
@@ -125,7 +125,11 @@ static int __io_msg_ring_data(struct io_ring_ctx *target_ctx,
		return -EINVAL;
	if (!(msg->flags & IORING_MSG_RING_FLAGS_PASS) && msg->dst_fd)
		return -EINVAL;
	if (target_ctx->flags & IORING_SETUP_R_DISABLED)
	/*
	 * Keep IORING_SETUP_R_DISABLED check before submitter_task load
	 * in io_msg_data_remote() -> io_msg_remote_post()
	 */
	if (smp_load_acquire(&target_ctx->flags) & IORING_SETUP_R_DISABLED)
		return -EBADFD;

	if (io_msg_need_remote(target_ctx))
@@ -245,7 +249,11 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
		return -EINVAL;
	if (target_ctx == ctx)
		return -EINVAL;
	if (target_ctx->flags & IORING_SETUP_R_DISABLED)
	/*
	 * Keep IORING_SETUP_R_DISABLED check before submitter_task load
	 * in io_msg_fd_remote()
	 */
	if (smp_load_acquire(&target_ctx->flags) & IORING_SETUP_R_DISABLED)
		return -EBADFD;
	if (!msg->src_file) {
		int ret = io_msg_grab_file(req, issue_flags);
+2 −1
Original line number Diff line number Diff line
@@ -193,7 +193,8 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx)
	if (ctx->restrictions.registered)
		ctx->restricted = 1;

	ctx->flags &= ~IORING_SETUP_R_DISABLED;
	/* Keep submitter_task store before clearing IORING_SETUP_R_DISABLED */
	smp_store_release(&ctx->flags, ctx->flags & ~IORING_SETUP_R_DISABLED);
	if (ctx->sq_data && wq_has_sleeper(&ctx->sq_data->wait))
		wake_up(&ctx->sq_data->wait);
	return 0;