{"id":"CVE-2026-99205","revision":"a6e6547c11784ddfb8790743da82878a","records":[{"revision":"a6e6547c11784ddfb8790743da82878a","observedAt":"2026-10-28T11:27:43.363+00:00","statement":{"source":"cve-program","id":"CVE-2026-99205","aliases":[],"title":"sched/core: Call wakeup_preempt() for queued tasks during class change","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nsched/core: Call wakeup_preempt() for queued tasks during class change\n\nPaul reported recent RCU changes exposed a lost resched where CPU idles\nwith a rcutorture thread waiting while being completely runnable.\n\nDumping the rq state at the time of idling with runnable tasks showed\nthe following:\n\n  rq->next_class = &fair_sched_class\n  rq->nr_running = 1\n  rq->cfs.h_nr_queued = 0\n  rq->rt.rt_nr_running = 1\n\nAlthough the waiting task was an RT task, \"rq->next_class\" did not point\nto rt_sched_class and was stuck at the lower priority fair_sched_class.\n\nInspecting sched_change_end() revealed the following race with\n__sched_setscheduler() for queued, but non-running tasks:\n\n    CPU0                                   CPU1\n    ====                                   ====\n\n  __schedule()\n\n    /*\n     * rq->donor is a fair task that blocks.\n     * rq->next_class = &fair_sched_class\n     */\n\n    rq_lock(rq0)\n\n    pick_next_task()\n      /* nr_running = 0 */\n      pick_task_fair()\n        sched_balance_newidle()\n          raw_spin_rq_unlock(rq0)\n                                    rq_lock(rq0)\n\n                                    activate_task(rq0, p)\n                                      /* p is a fair task */\n                                      rq0->nr_running++;\n                                      rq0->cfs.h_nr_queued++;\n                                      wakeup_preempt(rq, p)\n                                        rq->next_class = &fair_sched_class\n                                        resched_curr()\n\n                                    rq_unlock(rq0)\n\n                                    __sched_setscheduler(p)\n                                      /* p is moved to SCHED_RR */\n                                      task_rq_lock(p)\n                                      sched_change_begin()\n\n\t\t\t\t      rq0->cfs.h_nr_queued--;\n\t\t\t\t      rq0->rt.rt_nr_running++;\n\n                                      sched_change_end()\n                                        /*\n                                         * p->on_rq = 1 (ctx->queued)\n                                         * but p is not rq->donor\n                                         * (!ctx->running) hence\n                                         * resched_curr() is and\n                                         * rq->next_class upgrade is\n                                         * skipped.\n                                         */\n\n                                       task_rq_unlock()\n\n          raw_spin_rq_lock(rq0)\n\n          /*\n           * rq->nr_running = 1\n           * rq->cfs.h_nr_queued = 0\n           * rq->rt.rt_nr_running = 1\n           * rq->next_class = &fair_sched_class\n           */\n\n           if (rq->cfs.h_nr_queued && ...)\n             /* Above is false */\n\n           if (rq_modified_above(this_rq, &fair_sched_class))\n             /* Also false since rq->next_class is still fair */\n\n      /*\n       * sched_balance_newidle() is considered to\n       * have failed to pull any fair tasks and no\n       * other wakeups were detected.\n       */\n       return NULL; /* pick_task_fair() */\n\n    pick_task_idle()\n      return rq->idle;\n\n    next = rq->idle;\n\n    /* Preemption indicators are lost */\n    clear_tsk_need_resched(prev);\n    clear_preempt_need_resched();\n\n    rq->curr = rq->idle;\n\n  !!! rq->idle switches in with rq->running == 1 but !need_resched() !!!\n\nIn simple words, enqueue, followed by a class change of the newly queued\ntask goes unnoticed in rq->next_class indicator and\nsched_balance_newidle() sees no fair task, nor any higher priority task\nenqueued.\n\nThe above sequence will lead to CPU idling with a runnable task on the\nCPU.\n\nCall wakeup_preempt() for ctx->queued cases in sched_change_end() to\nre-evaluate rq->next_class after class change (ENQUEUE_CLASS) and set\nthe NEED_RESCHED indicator accordingly.\n\nNewidle balance will correctly see an enqueue of a higher priority\nt\n---truncated---","state":0,"publishedAt":"2026-10-28T10:35:59.093+00:00","modifiedAt":"2026-10-28T10:35:59.093+00:00","affected":[{"ecosystem":"Vendor product","name":"Linux","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"product\": \"Linux\",\n                    \"vendor\": \"Linux\",\n                    \"defaultStatus\": \"unaffected\",\n                    \"repo\": \"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\n                    \"programFiles\": [\n                        \"kernel/sched/core.c\"\n                    ],\n                    \"versions\": [\n                        {\n                            \"version\": \"704069649b5bfb7bf1fe32c0281fe9036806a59a\",\n                            \"lessThan\": \"ae89744c5ebf299bf55ac7581768fbd9f119a903\",\n                            \"status\": \"affected\",\n                            \"versionType\": \"git\"\n                        },\n                        {\n                            \"version\": \"704069649b5bfb7bf1fe32c0281fe9036806a59a\",\n                            \"lessThan\": \"118a2cf4ced60777a2408001e2b4838fed1cea55\",\n                            \"status\": \"affected\",\n                            \"versionType\": \"git\"\n                        }\n                    ]\n                }"},{"ecosystem":"Vendor product","name":"Linux","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"product\": \"Linux\",\n                    \"vendor\": \"Linux\",\n                    \"defaultStatus\": \"affected\",\n                    \"repo\": \"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\n                    \"programFiles\": [\n                        \"kernel/sched/core.c\"\n                    ],\n                    \"versions\": [\n                        {\n                            \"version\": \"7.0\",\n                            \"status\": \"affected\"\n                        },\n                        {\n                            \"version\": \"0\",\n                            \"lessThan\": \"7.0\",\n                            \"status\": \"unaffected\",\n                            \"versionType\": \"semver\"\n                        },\n                        {\n                            \"version\": \"7.2.13\",\n                            \"lessThanOrEqual\": \"7.2.*\",\n                            \"status\": \"unaffected\",\n                            \"versionType\": \"semver\"\n                        },\n                        {\n                            \"version\": \"7.3\",\n                            \"lessThanOrEqual\": \"*\",\n                            \"status\": \"unaffected\",\n                            \"versionType\": \"original_commit_for_fix\"\n                        }\n                    ]\n                }"}],"metrics":[],"references":["https://git.kernel.org/stable/c/ae89744c5ebf299bf55ac7581768fbd9f119a903","https://git.kernel.org/stable/c/118a2cf4ced60777a2408001e2b4838fed1cea55"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-99205","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-99205","identifiers":["CVE-2026-99205"]},"retained":false,"historicalAffected":[]}],"coverage":[]}