Re: [PATCH] io_uring: validate user-controlled cq.head in io_cqe_cache_refill()
From: Jens Axboe
Date: Wed May 13 2026 - 10:24:25 EST
On 5/13/26 12:32 AM, Zizhi Wo wrote:
> diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
> index 4ed998d60c09..92e255e9e08f 100644
> --- a/io_uring/io_uring.c
> +++ b/io_uring/io_uring.c
> @@ -710,11 +710,13 @@ static bool io_fill_nop_cqe(struct io_ring_ctx *ctx, unsigned int off)
> * fill the cq entry
> */
> bool io_cqe_cache_refill(struct io_ring_ctx *ctx, bool overflow, bool cqe32)
> {
> struct io_rings *rings = ctx->rings;
> - unsigned int off = ctx->cached_cq_tail & (ctx->cq_entries - 1);
> + unsigned int head = READ_ONCE(ctx->rings->cq.head);
> + unsigned int tail = ctx->cached_cq_tail;
> + unsigned int off = tail & (ctx->cq_entries - 1);
> unsigned int free, queued, len;
This looks wrong, as you're snapshotting 'tail' while it could get
modified by if a nop fill before the refill happens. And fwiw, looks
like the refill part potentially suffers from the same unsigned issue.
--
Jens Axboe