CVE-2026-99252: io_uring/mpscq: disable preemption while pushing
In the Linux kernel, the following vulnerability has been resolved:
iouring/mpscq: disable preemption while pushing
A push makes the node the new tail, and then links it to its predecessor. In between the queue isn't empty, but mpscqpop() can't get at the node. The consumers deal with that by trying again, with a condresched() in the loop to give a preempted producer the chance to finish.
condresched() doesn't do that if the consumer has a higher priority than the producer and both have to use the same CPU:
producer (SCHEDOTHER) consumer (SCHEDFIFO), same CPU ioreqlocalworkadd() mpscqpush() prev = xchg(&q->tail, node) <preempted> iocqringwait() iorunlocalwork() again: condresched() // nothing to do mpscqpop() // NULL // work pending, no events yet goto again
The producer can be any task that is able to queue taskwork for the ring: an io-wq worker, or somebody who sends a message with IORINGOPMSGRING. The consumer spins, holding ->uringlock, until the scheduler takes pity on the fair class, which takes about a second with the default settings of the fair server, and forever without it. The loops in tctxtaskworkrun() and iocancellocaltaskwork() have the same problem.
Don't allow preemption between the two steps. That bounds the time the window is open on the CPU of the producer by what interrupts take, and a consumer that waits for that is on another CPU. The cost is a preemptdisable()/preemptenable() pair per push.