PT-2026-128198

CVE-2026-99205

·

Published

2026-10-28

·

Updated

2026-10-28

Description by

Score
N/A
Not available

No severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.

In the Linux kernel, the following vulnerability has been resolved:
sched/core: Call wakeup preempt() 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->next class = &fair sched class rq->nr running = 1 rq->cfs.h nr queued = 0 rq->rt.rt nr running = 1
Although the waiting task was an RT task, "rq->next class" did not point to rt sched class and was stuck at the lower priority fair sched class.
Inspecting sched change end() revealed the following race with sched setscheduler() for queued, but non-running tasks:
CPU0 CPU1 ==== ====
schedule()
/*
  • rq->donor is a fair task that blocks.
  • rq->next class = &fair sched class */
rq lock(rq0)
pick next task() /* nr running = 0 */ pick task fair() sched balance newidle() raw spin rq unlock(rq0) rq lock(rq0)
              activate task(rq0, p)
               /* p is a fair task */
               rq0->nr running++;
               rq0->cfs.h nr queued++;
               wakeup preempt(rq, p)
                rq->next class = &fair sched class
                resched curr()

              rq unlock(rq0)

               sched setscheduler(p)
               /* p is moved to SCHED RR */
               task rq lock(p)
               sched change begin()

			   rq0->cfs.h nr queued--;
			   rq0->rt.rt nr running++;

               sched change end()
                /*
                 * p->on rq = 1 (ctx->queued)
                 * but p is not rq->donor
                 * (!ctx->running) hence
                 * resched curr() is and
                 * rq->next class upgrade is
                 * skipped.
                 */

                task rq unlock()

 raw spin rq lock(rq0)

 /*
  * rq->nr running = 1
  * rq->cfs.h nr queued = 0
  * rq->rt.rt nr running = 1
  * rq->next class = &fair sched class
  */

  if (rq->cfs.h nr queued && ...)
   /* Above is false */

  if (rq modified above(this rq, &fair sched class))
   /* Also false since rq->next class is still fair */
/* * sched balance newidle() is considered to * have failed to pull any fair tasks and no * other wakeups were detected. / return NULL; / pick task fair() */
pick task idle() return rq->idle;
next = rq->idle;
/* Preemption indicators are lost */ clear tsk need resched(prev); clear preempt need resched();
rq->curr = rq->idle;
!!! rq->idle switches in with rq->running == 1 but !need resched() !!!
In simple words, enqueue, followed by a class change of the newly queued task goes unnoticed in rq->next class indicator and sched balance newidle() 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 wakeup preempt() for ctx->queued cases in sched change end() to re-evaluate rq->next class after class change (ENQUEUE CLASS) and set the NEED RESCHED indicator accordingly.
Newidle balance will correctly see an enqueue of a higher priority t ---truncated---
Vendors
Affected products
Related identifiers
Found an issue in the description? Have something to add? Feel free to write us 👾