In the Linux kernel, the following vulnerability has been resolved:
bpf: Disable preemption in bpf_get_stackid
The get_perf_callchain call needs disabled preemption plus we need
it disabled as long as we access its returned trace entries buffer.
Note the bpf_get_stackid_pe function is executed already with
preemption disabled.
CVSS Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7.8
AV:L - bpf_get_stackid is a tracing BPF helper (kprobe, tracepoint, raw_tp, perf_event, tracing/fentry) reached only after a local bpf(2) PROG_LOAD and attach; kernel CNA guidance classifies BPF as Local, with no network or USB path into this helper.
AC:L - The attacker controls both sides of the race: a preemptible raw_tp/tracing program with a small STACK_TRACE map, and a same-CPU get_perf_callchain with larger max_depth that reuses the per-CPU entry after put_callchain_entry(). On PREEMPT kernels (e.g. Android) raw_tp uses migrate_disable only, so pinning and retries make the window reliably hittable.
PR:L - Loading the required tracing programs needs CAP_BPF and CAP_PERFMON at bpf_prog_load(), and STACK_TRACE maps need CAP_BPF. Per kernel CNA guidance these are Low because BPF tokens and user namespaces can delegate them to non-init-namespace users, not only real root.
UI:N - The attacker loads their own BPF program, attaches it to a tracepoint they can fire, and invokes bpf_get_stackid through their own syscalls or pinned threads; no victim mount, file open, or other user action is required.
S:U - The out-of-bounds write corrupts the stack-map bucket slab inside the same host kernel security authority, enabling local privilege escalation; it does not cross a VM, IOMMU, or other distinct trust boundary.
C:H - After put_callchain_entry(), a reused per-CPU entry can inflate trace->nr so memcpy/jhash2 and the build-id loop copy kernel instruction pointers past the attacker-sized stack_map_bucket, which is kernel memory corruption that can be turned into an arbitrary read primitive.
I:H - Without a remaining size cap on the reused trace->nr, memcpy into the preallocated stack_map_bucket (sized to a small map value_size) or the bpf_stack_build_id store loop is an attacker-sized kernel heap OOB write, up to PERF_MAX_STACK_DEPTH frames, that can smash adjacent slab and hijack control flow.
A:H - The same unbounded heap write past a small stack-map bucket causes a kernel oops or panic even when not fully weaponized, matching CNA guidance that any kernel crash or memory-corrupting OOB write is Availability High.
| Attack Vector |
Local |
Scope |
Unchanged |
| Attack Complexity |
Low |
Confidentiality Impact |
High |
| Privileges Required |
Low |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:L - bpf_get_stackid is a tracing BPF helper (kprobe, tracepoint, raw_tp, perf_event, tracing/fentry) reached only after a local bpf(2) PROG_LOAD and attach; kernel CNA guidance classifies BPF as Local, with no network or USB path into this helper.
AC:L - The attacker controls both sides of the race: a preemptible raw_tp/tracing program with a small STACK_TRACE map, and a same-CPU get_perf_callchain with larger max_depth that reuses the per-CPU entry after put_callchain_entry(). On PREEMPT kernels (e.g. Android) raw_tp uses migrate_disable only, so pinning and retries make the window reliably hittable.
PR:L - Loading the required tracing programs needs CAP_BPF and CAP_PERFMON at bpf_prog_load(), and STACK_TRACE maps need CAP_BPF. Per kernel CNA guidance these are Low because BPF tokens and user namespaces can delegate them to non-init-namespace users, not only real root.
UI:N - The attacker loads their own BPF program, attaches it to a tracepoint they can fire, and invokes bpf_get_stackid through their own syscalls or pinned threads; no victim mount, file open, or other user action is required.
S:U - The out-of-bounds write corrupts the stack-map bucket slab inside the same host kernel security authority, enabling local privilege escalation; it does not cross a VM, IOMMU, or other distinct trust boundary.
C:H - After put_callchain_entry(), a reused per-CPU entry can inflate trace->nr so memcpy/jhash2 and the build-id loop copy kernel instruction pointers past the attacker-sized stack_map_bucket, which is kernel memory corruption that can be turned into an arbitrary read primitive.
I:H - Without a remaining size cap on the reused trace->nr, memcpy into the preallocated stack_map_bucket (sized to a small map value_size) or the bpf_stack_build_id store loop is an attacker-sized kernel heap OOB write, up to PERF_MAX_STACK_DEPTH frames, that can smash adjacent slab and hijack control flow.
A:H - The same unbounded heap write past a small stack-map bucket causes a kernel oops or panic even when not fully weaponized, matching CNA guidance that any kernel crash or memory-corrupting OOB write is Availability High.
CVSS 3.1