Unverified Commit 62b6fca2 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!12906 io_uring: fix CVE-2024-50060

Merge Pull Request from: @ci-robot 
 
PR sync from: Baokun Li <libaokun1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/FT47X6BSAT7BSYKRZKVZOBWTY4MQZHFN/ 
Jens Axboe (1):
  io_uring: check if we need to reschedule during overflow flush

Pavel Begunkov (1):
  io_uring: always lock __io_cqring_overflow_flush


-- 
2.46.1
 
https://gitee.com/src-openeuler/kernel/issues/IAYRF9 
 
Link:https://gitee.com/openeuler/kernel/pulls/12906

 

Reviewed-by: default avatarZhang Peng <zhangpeng362@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 865d9554 d7a6ae40
Loading
Loading
Loading
Loading
+23 −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;

@@ -701,6 +705,21 @@ static void __io_cqring_overflow_flush(struct io_ring_ctx *ctx)
		memcpy(cqe, &ocqe->cqe, cqe_size);
		list_del(&ocqe->list);
		kfree(ocqe);

		/*
		 * For silly syzbot cases that deliberately overflow by huge
		 * amounts, check if we need to resched and drop and
		 * reacquire the locks if so. Nothing real would ever hit this.
		 * Ideally we'd have a non-posting unlock for this, but hard
		 * to care for a non-real case.
		 */
		if (need_resched()) {
			io_cq_unlock_post(ctx);
			mutex_unlock(&ctx->uring_lock);
			cond_resched();
			mutex_lock(&ctx->uring_lock);
			io_cq_lock(ctx);
		}
	}

	if (list_empty(&ctx->cq_overflow_list)) {
@@ -712,11 +731,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 +1612,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;