DEBIAN-CVE-2026-99205: Debian/linux vulnerability
In the Linux kernel, the following vulnerability has been resolved: sched/core: Call wakeuppreempt() for queued tasks during class change Paul reported recent RCU changes exposed a lost resched where CPU idles with a rcutorture thread waiting while being completely runnable. Dumping the rq state at the time of idling with runnable tasks showed the following: rq->nextclass = &fairschedclass rq->nrrunning = 1 rq->cfs.hnrqueued = 0 rq->rt.rtnrrunning = 1 Although the waiting task was an RT task, "rq->nextclass" did not point to rtschedclass and was stuck at the lower priority fairschedclass. Inspecting schedchangeend() revealed the following race with schedsetscheduler() for queued, but non-running tasks: CPU0 CPU1 ==== ==== schedule() / rq->donor is a fair task that blocks. rq->nextclass = &fairschedclass / rqlock(rq0) picknexttask() / nrrunning = 0 / picktaskfair() schedbalancenewidle() rawspinrqunlock(rq0) rqlock(rq0) activatetask(rq0, p) / p is a fair task / rq0->nrrunning++; rq0->cfs.hnrqueued++; wakeuppreempt(rq, p) rq->nextclass = &fairschedclass reschedcurr() rqunlock(rq0) schedsetscheduler(p) / p is moved to SCHEDRR / taskrqlock(p) schedchangebegin() rq0->cfs.hnrqueued--; rq0->rt.rtnrrunning++; schedchangeend() / p->onrq = 1 (ctx->queued) but p is not rq->donor (!ctx->running) hence reschedcurr() is and rq->nextclass upgrade is skipped. / taskrqunlock() rawspinrqlock(rq0) / rq->nrrunning = 1 rq->cfs.hnrqueued = 0 rq->rt.rtnrrunning = 1 rq->nextclass = &fairschedclass / if (rq->cfs.hnrqueued && ...) / Above is false / if (rqmodifiedabove(thisrq, &fairschedclass)) / Also false since rq->nextclass is still fair / / schedbalancenewidle() is considered to have failed to pull any fair tasks and no other wakeups were detected. / return NULL; / picktaskfair() / picktaskidle() return rq->idle; next = rq->idle; / Preemption indicators are lost / cleartskneedresched(prev); clearpreemptneedresched(); rq->curr = rq->idle; !!! rq->idle switches in with rq->running == 1 but !needresched() !!! In simple words, enqueue, followed by a class change of the newly queued task goes unnoticed in rq->nextclass indicator and schedbalancenewidle() sees no fair task, nor any higher priority task enqueued. The above sequence will lead to CPU idling with a runnable task on the CPU. Call wakeuppreempt() for ctx->queued cases in schedchangeend() to re-evaluate rq->nextclass after class change (ENQUEUECLASS) and set the NEEDRESCHED indicator accordingly. Newidle balance will correctly see an enqueue of a higher priority t ---truncated---
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Call wakeup_preempt() for ctx->queued cases in sched_change_end() after a class change, such as ENQUEUE_CLASS, to re-evaluate rq->next_class and set the NEED_RESCHED indicator accordingly.