Cloudanix VulnDB

CVE-2026-89580

High · 7.8

CVSS

7.8

EPSS

0.1%

Published

Sep 11, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A bug in the Linux kernel can let certain local programs overwrite memory they should not reach, which could let an attacker on the machine take control or crash the system.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Moderate
Impact
Full Compromise
Component
OS kernel
Class
Race Condition
Remediation
Patch
Effort
Medium
Patch risk
Low

What it actually does

Race condition in __bpf_get_stack allows a preemptible BPF program to be descheduled after obtaining a per-CPU perf_callchain_entry, enabling another task on the same CPU to reuse and overwrite the buffer; subsequent memcpy uses an inflated trace->nr value and performs an out-of-bounds write into the caller's buffer or build-ID path.

Why it matters to the business

Local attackers on affected Linux systems can corrupt kernel memory, potentially leading to privilege escalation, system crashes, or arbitrary code execution; the issue affects kernels running BPF programs under preemption and requires urgent patching to maintain system integrity.

How an attack unfolds

An attacker loads a BPF program that triggers __bpf_get_stack, schedules itself out between buffer acquisition and copy, allows another task to reuse the per-CPU entry and inflate nr, then resumes to trigger the oversized memcpy that writes beyond the caller's buffer.

How to fix it

Apply the upstream kernel patch that wraps the callchain acquisition and copy with preempt_disable(); rebuild and reboot onto a fixed kernel version; disable untrusted BPF program loading until patched if immediate upgrade is not feasible.

How to confirm the fix worked

Confirm the patch is present by inspecting the __bpf_get_stack function for the added preempt_disable/enable pair around get_perf_callchain and the subsequent copy; run kernel self-tests exercising BPF callchain collection under preemption; verify no OOB write occurs via memory sanitizer or fuzzing.

Typical attack path

  1. Compile and load a non-sleepable raw tracepoint or similar BPF program that invokes __bpf_get_stack
  2. Trigger preemption or migration between callchain entry retrieval and the memcpy
  3. Force another task on the same CPU to reuse the perf_callchain_entry and increase trace->nr
  4. Resume the original program so that copy_len exceeds the caller's buffer size
  5. Achieve out-of-bounds write to corrupt adjacent kernel memory

How to detect it

Search kernel logs and audit trails for unexpected BPF program loads followed by kernel oops or warnings referencing perf_callchain or __bpf_get_stack; examine crash dumps for memcpy overruns originating from BPF stack retrieval paths.

What your security team should do

  • Prioritize kernel upgrade on all systems exposing BPF to untrusted users
  • Restrict BPF program loading via LSM or capabilities until patches are deployed
  • Monitor for local privilege-escalation attempts via audit logs of BPF operations
  • Test the fix in a staging environment that reproduces preemption scenarios before broad rollout

The record

In the Linux kernel, the following vulnerability has been resolved: bpf: Disable preemption in __bpf_get_stack get_perf_callchain() returns a per-CPU perf_callchain_entry buffer and releases its recursion slot via put_callchain_entry() before returning, so nothing keeps the entry reserved while __bpf_get_stack() consumes it below. A preemptible BPF program (e.g. a non-sleepable raw tracepoint program on a PREEMPT kernel, which runs under migrate_disable() but not preempt_disable()) can be scheduled out between obtaining the entry and the copy. Another task scheduled on the same CPU then reuses the same per-CPU buffer and overwrites trace->nr with a larger value. copy_len is then computed from the inflated trace->nr and can exceed the caller's buffer, causing an out-of-bounds write in the memcpy() and in the build_id path. The rcu_read_lock() taken here alone does not prevent this. It is only taken on the may_fault path, and under CONFIG_PREEMPT_RCU it does not disable preemption; it merely keeps perf's callchain buffer array alive (freed via call_rcu()) and does nothing to stop another task from reusing the entry. Disable preemption around obtaining the callchain entry and copying it into the caller's buffer, so the entry cannot be reused underneath us and trace->nr stays bounded by max_depth. Build ID resolution may fault and is therefore deferred until after preemption is re-enabled; by then the instruction pointers have already been copied into buf, so it operates only on that private copy. Note, preempt_disable() also subsumes the buffer-lifetime guarantee the rcu_read_lock() provided, since a preempt-disabled section is an RCU read-side critical section for the callchain buffers' call_rcu() reclaim. [ changed Fixes: commit ]

Affected packages

Ecosystem Package Introduced Fixed