CVE-2025-39780 (GCVE-0-2025-39780)
Vulnerability from cvelistv5
Published
2025-09-11 16:56
Modified
2026-08-05 12:05
Severity ?
VLAI Severity ?
EPSS score ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
sched/ext: Fix invalid task state transitions on class switch
When enabling a sched_ext scheduler, we may trigger invalid task state
transitions, resulting in warnings like the following (which can be
easily reproduced by running the hotplug selftest in a loop):
sched_ext: Invalid task state transition 0 -> 3 for fish[770]
WARNING: CPU: 18 PID: 787 at kernel/sched/ext.c:3862 scx_set_task_state+0x7c/0xc0
...
RIP: 0010:scx_set_task_state+0x7c/0xc0
...
Call Trace:
<TASK>
scx_enable_task+0x11f/0x2e0
switching_to_scx+0x24/0x110
scx_enable.isra.0+0xd14/0x13d0
bpf_struct_ops_link_create+0x136/0x1a0
__sys_bpf+0x1edd/0x2c30
__x64_sys_bpf+0x21/0x30
do_syscall_64+0xbb/0x370
entry_SYSCALL_64_after_hwframe+0x77/0x7f
This happens because we skip initialization for tasks that are already
dead (with their usage counter set to zero), but we don't exclude them
during the scheduling class transition phase.
Fix this by also skipping dead tasks during class swiching, preventing
invalid task state transitions.
References
Impacted products
{
"containers": {
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"kernel/sched/ext.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "786f6314604b34c3e7de5f733f4e08e35c448a50",
"status": "affected",
"version": "a8532fac7b5d27b8d62008a89593dccb6f9786ef",
"versionType": "git"
},
{
"lessThan": "6a32cbe95029ebe21cc08349fd7ef2a3d32d2043",
"status": "affected",
"version": "a8532fac7b5d27b8d62008a89593dccb6f9786ef",
"versionType": "git"
},
{
"lessThan": "ddf7233fcab6c247379d0928d46cc316ee122229",
"status": "affected",
"version": "a8532fac7b5d27b8d62008a89593dccb6f9786ef",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"kernel/sched/ext.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "6.12"
},
{
"lessThan": "6.12",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.12.*",
"status": "unaffected",
"version": "6.12.44",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.16.*",
"status": "unaffected",
"version": "6.16.4",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "6.17",
"versionType": "original_commit_for_fix"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.12.44",
"versionStartIncluding": "6.12",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.16.4",
"versionStartIncluding": "6.12",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.17",
"versionStartIncluding": "6.12",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nsched/ext: Fix invalid task state transitions on class switch\n\nWhen enabling a sched_ext scheduler, we may trigger invalid task state\ntransitions, resulting in warnings like the following (which can be\neasily reproduced by running the hotplug selftest in a loop):\n\n sched_ext: Invalid task state transition 0 -\u003e 3 for fish[770]\n WARNING: CPU: 18 PID: 787 at kernel/sched/ext.c:3862 scx_set_task_state+0x7c/0xc0\n ...\n RIP: 0010:scx_set_task_state+0x7c/0xc0\n ...\n Call Trace:\n \u003cTASK\u003e\n scx_enable_task+0x11f/0x2e0\n switching_to_scx+0x24/0x110\n scx_enable.isra.0+0xd14/0x13d0\n bpf_struct_ops_link_create+0x136/0x1a0\n __sys_bpf+0x1edd/0x2c30\n __x64_sys_bpf+0x21/0x30\n do_syscall_64+0xbb/0x370\n entry_SYSCALL_64_after_hwframe+0x77/0x7f\n\nThis happens because we skip initialization for tasks that are already\ndead (with their usage counter set to zero), but we don\u0027t exclude them\nduring the scheduling class transition phase.\n\nFix this by also skipping dead tasks during class swiching, preventing\ninvalid task state transitions."
}
],
"metrics": [
{
"cvssV3_1": {
"baseScore": 7.8,
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"scenarios": [
{
"lang": "en",
"value": "AV:L - The vulnerable path is entered through the local `bpf(BPF_LINK_CREATE)` syscall attaching a sched_ext struct_ops scheduler, combined with local task fork/exit churn to populate the race window. No network-reachable code is involved.\nAC:L - The attacker controls both sides of the race \u2014 generating a storm of exiting tasks (each of which sits on `scx_tasks` with `usage == 0` for a full RCU grace period, since `put_task_struct()` always defers via `call_rcu()`) while repeatedly enabling a scheduler; upstream states it is \"easily reproduced by running the hotplug selftest in a loop\".\nPR:L - Enabling a sched_ext scheduler needs only `bpf_token_capable(CAP_BPF)`, which is delegable to unprivileged users in user namespaces via BPF tokens (and is open on `unprivileged_bpf_disabled=0` systems); on deployments where a daemon such as scx_loader switches schedulers, a wholly unprivileged user supplies the dying-task half of the race.\nUI:N - The entire sequence \u2014 scheduler attach plus fork/exit churn \u2014 is driven by the attacker\u0027s own processes. No victim action is required.\nS:U - The corruption is confined to kernel scheduler state within the same security authority; no VM, IOMMU, or sandbox boundary is crossed.\nC:H - The code reads and writes a `task_struct` whose usage refcount has already reached zero and which is queued for RCU-deferred destruction \u2014 the exact condition the `Fixes:` commit identifies as a use-after-free hazard \u2014 and drives BPF `ops.enable()`/`ops.exit_task()` against a task with no allocated per-task context, exposing stale/foreign scheduler state.\nI:H - `p-\u003esched_class` (a pointer to the scheduling-class function-pointer dispatch table), `p-\u003escx.slice`, and `p-\u003escx.flags` are written into an object that is mid-teardown and pending free, and the sched_ext task state machine is forced through an illegal `NONE -\u003e ENABLED` transition that corrupts BPF-scheduler per-task accounting.\nA:H - The bug triggers a `WARN_ONCE()` splat in `scx_set_task_state()`, which is an immediate kernel panic on the many hardened, cloud, Android, and CI configurations that set `panic_on_warn`; additionally the resulting contract violation makes real BPF schedulers call `scx_bpf_error()`, ejecting the scheduler and disrupting scheduling system-wide."
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-08-05T12:05:05.360Z",
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux"
},
"references": [
{
"url": "https://git.kernel.org/stable/c/786f6314604b34c3e7de5f733f4e08e35c448a50"
},
{
"url": "https://git.kernel.org/stable/c/6a32cbe95029ebe21cc08349fd7ef2a3d32d2043"
},
{
"url": "https://git.kernel.org/stable/c/ddf7233fcab6c247379d0928d46cc316ee122229"
}
],
"title": "sched/ext: Fix invalid task state transitions on class switch",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"assignerShortName": "Linux",
"cveId": "CVE-2025-39780",
"datePublished": "2025-09-11T16:56:31.142Z",
"dateReserved": "2025-04-16T07:20:57.130Z",
"dateUpdated": "2026-08-05T12:05:05.360Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.
Loading…
Loading…