Commit d383ae29 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Baokun Li
Browse files

io_uring: always lock __io_cqring_overflow_flush

mainline inclusion
from mainline-v6.10-rc1
commit 8d09a88ef9d3cb7d21d45c39b7b7c31298d23998
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRF9
CVE: CVE-2024-50060

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8d09a88ef9d3cb7d21d45c39b7b7c31298d23998



--------------------------------

Conditional locking is never great, in case of
__io_cqring_overflow_flush(), which is a slow path, it's not justified.
Don't handle IOPOLL separately, always grab uring_lock for overflow
flushing.

Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/162947df299aa12693ac4b305dacedab32ec7976.1712708261.git.asml.silence@gmail.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>

Conflicts:
	io_uring/io_uring.c
[Context differences because there is no commit
 408024b95927 ("io_uring: open code io_cqring_overflow_flush()").]
Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
parent bc1376a3
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -667,6 +667,8 @@ static void io_cqring_overflow_kill(struct io_ring_ctx *ctx)
	struct io_overflow_cqe *ocqe;
	LIST_HEAD(list);

	lockdep_assert_held(&ctx->uring_lock);

	spin_lock(&ctx->completion_lock);
	list_splice_init(&ctx->cq_overflow_list, &list);
	clear_bit(IO_CHECK_CQ_OVERFLOW_BIT, &ctx->check_cq);
@@ -683,6 +685,8 @@ static void __io_cqring_overflow_flush(struct io_ring_ctx *ctx)
{
	size_t cqe_size = sizeof(struct io_uring_cqe);

	lockdep_assert_held(&ctx->uring_lock);

	if (__io_cqring_events(ctx) == ctx->cq_entries)
		return;

@@ -712,11 +716,8 @@ static void __io_cqring_overflow_flush(struct io_ring_ctx *ctx)

static void io_cqring_do_overflow_flush(struct io_ring_ctx *ctx)
{
	/* iopoll syncs against uring_lock, not completion_lock */
	if (ctx->flags & IORING_SETUP_IOPOLL)
	mutex_lock(&ctx->uring_lock);
	__io_cqring_overflow_flush(ctx);
	if (ctx->flags & IORING_SETUP_IOPOLL)
	mutex_unlock(&ctx->uring_lock);
}

@@ -1596,6 +1597,8 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, long min)
	unsigned int nr_events = 0;
	unsigned long check_cq;

	lockdep_assert_held(&ctx->uring_lock);

	if (!io_allowed_run_tw(ctx))
		return -EEXIST;