Re: [PATCH] io_uring/fdinfo: ignore IORING_CQE_F_32 in last CQ array slot
From: Jens Axboe
Date: Fri Sep 11 2026 - 12:04:23 EST
On 9/11/26 9:44 AM, Jann Horn wrote:
> On Fri, Sep 11, 2026 at 5:35?PM Jann Horn <jannh@xxxxxxxxxx> wrote:
>> A cqe32 entry spans two CQ array slots, so the last CQ array slot can't
>> contain a cqe32 entry. If the CQ tail points at the last CQ array slot and
>> the kernel wants to write a cqe32 entry, it uses io_fill_nop_cqe() to pad
>> the last CQ array slot with a dummy entry and make the tail wrap around.
>>
>> However, malicious userspace can directly set IORING_CQE_F_32 on the last
>> CQ array slot, causing __io_uring_show_fdinfo() to read the second cqe32
>> half from beyond the CQ array. Change __io_uring_show_fdinfo() to
>> explicitly ignore the IORING_CQE_F_32 flag in this case.
>>
>> This is not a real bugfix, just tightening the code a bit, because:
>>
>> 1. the number of CQE slots is always a power of 2, see io_uring_fill_params
>> 2. the ring_region region consists of:
>> - a 64-byte header
>> - pow(2, N) CQE slots (each 0x10 bytes)
>> - optionally, the SQ array
>> 3. the ring_region size must be page-aligned because it is shared memory
>>
>> Together, these properties imply that the last CQE slot can't be close
>> before the end of a page, so the "out-of-bounds" data is
>
> Oops, sorry, somehow I forgot to complete that sentence, that was
> supposed to be:
>
> Together, these properties imply that the last CQE slot can't be close
> before the end of a page, so the "out-of-bounds" data is in memory
> that is anyway accessible to userspace.
I did spot that as well, thanks for finishing it. Your fdinfo idea keeps
on giving, at least this one doesn't really matter :-)
--
Jens Axboe