CVE-2026-89516
NoneCVSS
—
EPSS
0.2%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A timing bug in a Linux kernel scheduling feature can crash the computer if a work queue is removed while tasks are still waiting to be put back on it.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
A race in the Linux kernel sched_ext subsystem can fire a BUG_ON and panic the kernel. scx_bpf_dsq_reenq() queues a deferred reenqueue that later runs from run_deferred()/process_deferred_reenq_users(), not from ops.dispatch(). If destroy_dsq() runs first, it does not flush pending deferred reenqueue users, so the handler can observe dsq->id == SCX_DSQ_INVALID and hit BUG_ON. A related TOCTOU existed if the id was read twice (validity check then BUG_ON); destroy_dsq() could invalidate the id between those reads. The issue is local availability loss via kernel crash, not remote code execution, information disclosure, or privilege escalation.
Why it matters to the business
Hosts that actually run sched_ext BPF schedulers can suffer unexpected kernel panics, reboots, and workload interruption if custom dispatch queues are destroyed while deferred reenqueue work is still pending. Impact is operational downtime, not data theft or account takeover. Urgency is low for most estates: EPSS is about 0.002 and flat over 30 days, exploit maturity is none, the issue is not in CISA KEV, and it is not tied to ransomware. The record has been public for roughly 32 days. Prioritize only Linux systems that load sched_ext schedulers; kernels without that feature are not exposed.
How an attack unfolds
There is no known in-the-wild campaign, named threat actor, or public exploit. Abuse requires local ability to exercise sched_ext (typically loading or influencing a BPF scheduler that creates DSQs and calls the deferred reenqueue helper, which implies BPF/admin-equivalent privilege or an already-loaded scheduler). The attacker arranges a deferred reenqueue against a live DSQ, then destroys that DSQ before run_deferred() processes the pending work. process_deferred_reenq_users() then sees an invalid DSQ id and BUG_ON, panicking the host. This is a local denial-of-service race against kernel scheduler-extension internals, not an unauthenticated network attack.
How to fix it
Install a kernel that includes the sched_ext fix: skip destroyed DSQs in process_deferred_reenq_users instead of BUG_ON, and read dsq->id once with READ_ONCE() so destroy_dsq() cannot invalidate the id between checks. Reboot into the patched kernel. No per-package fixed versions were supplied with this record, so take the patched build from your distro or kernel vendor by matching this CVE or the sched_ext deferred-reenq DSQ destroy fix. Until you can patch, do not run sched_ext BPF schedulers that create and destroy custom DSQs, and tightly restrict who may load BPF schedulers (CAP_BPF/CAP_SYS_ADMIN). Userspace workarounds cannot flush in-kernel deferred reenqueue state; the durable fix is the kernel update.
How to confirm the fix worked
Confirm the running kernel changelog, vendor advisory, or stable-tree commit includes the sched_ext change that skips destroyed DSQs in process_deferred_reenq_users and uses READ_ONCE for dsq->id. Compare uname -r to your vendor’s fixed kernel package. Hosts without CONFIG_SCHED_CLASS_EXT (or equivalent) and hosts that never load a sched_ext scheduler are not exposed. After patching, verify the BPF scheduler still attaches and that DSQ create/destroy under load no longer produces a kernel BUG/oops in sched_ext.
Typical attack path
- Obtain local influence on a Linux host whose kernel includes sched_ext and that runs (or can load) a BPF scheduler using custom dispatch queues.
- Cause a deferred DSQ reenqueue to be queued via the sched_ext BPF helper path.
- Destroy that dispatch queue before the deferred work is processed in run_deferred().
- Kernel hits BUG_ON in process_deferred_reenq_users on an invalid DSQ id and panics, denying service.
How to detect it
Successful abuse is a kernel BUG/oops/panic, not a stealthy implant. Search dmesg, journalctl --dmesg/-k, /var/log/kern.log, kdump/vmcore, pstore, and crash-dump analysis for BUG at kernel/sched/ext.c and call traces through process_deferred_reenq_users, run_deferred, scx_bpf_dsq_reenq, or destroy_dsq. Correlate the panic time with BPF scheduler load/unload or DSQ teardown. There are no network indicators, malware hashes, or named-actor TTPs. Benign sched_ext use can mention the subsystem in logs; treat a BUG_ON/oops in those functions as the signal, not mere presence of sched_ext.
- process_deferred_reenq_users
- kernel BUG at kernel/sched/ext.c
- scx_bpf_dsq_reenq
- SCX_DSQ_INVALID
- Call trace:.*scx_.*run_deferred
- Oops:.*invalid opcode.*sched/ext
What your security team should do
- Inventory Linux kernels with sched_ext enabled or with a BPF scheduler attached; patch and reboot those hosts first.
- Treat remaining systems as low urgency given EPSS ~0.002, no KEV listing, no ransomware use, and no known exploit, and fold the fix into the normal kernel cadence.
- Restrict CAP_BPF/CAP_SYS_ADMIN and sched_ext loader permissions so untrusted users cannot attach custom schedulers.
- Until patched, avoid production use of sched_ext schedulers that destroy custom DSQs while tasks may still be deferred-reenqueued.
- Alert on kernel oops/panic stacks that name process_deferred_reenq_users or kernel/sched/ext.c so a crash is triaged as this race rather than a generic hardware fault.
The record
In the Linux kernel, the following vulnerability has been resolved: sched_ext: Don't BUG_ON a destroyed DSQ in process_deferred_reenq_users scx_bpf_dsq_reenq() queues a deferred reenq (dru) that runs from run_deferred(), not ops.dispatch(). If the DSQ is destroyed before the dru runs, process_deferred_reenq_users() sees dsq->id == SCX_DSQ_INVALID and hits the BUG_ON. destroy_dsq() doesn't flush pending drus, so just skip. tj: Read dsq->id once with READ_ONCE(). Reading it separately in the INVALID check and the BUG_ON would leave a window where destroy_dsq() can invalidate the id between the two reads and still trigger the BUG_ON.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|