freenode
Kernel & Low-Level

BPF stack helpers race fixed to stop out-of-bounds writes

Preemptible programs could reuse a per-CPU callchain buffer and inflate the copy length past the caller's buffer.

Kernel developers are landing a fix for a long-standing race in BPF stack-trace helpers that could turn a preemptible program into an out-of-bounds memory write.

The helpers that walk call stacks (bpf_get_stack and bpf_get_stackid) rely on get_perf_callchain, which hands back a per-CPU buffer and immediately releases its recursion slot. On a PREEMPT kernel, a non-sleepable program that runs only under migrate_disable can be scheduled out while still reading that buffer. Another task on the same CPU then reuses the entry, overwrites the recorded depth with a larger value, and the original program copies past the end of the caller's buffer. RCU alone does not close the window: under CONFIG_PREEMPT_RCU it does not disable preemption, and it is not even taken on every path.

Jiri Olsa posted a twelve-part series that first factors the stack-id and callchain paths so preemption can be held only for the critical section, then disables preemption around obtaining the entry and copying it. Build-id work that may fault is deferred until after preemption is re-enabled, operating only on the private copy. Daniel Borkmann authored the core preemption fix for the get-stack path. The issue was first reported by Tao Chen, with a further report from STAR Labs; both fixes are marked for stable.

A related cleanup clears the user buffer on error paths in the task-stack helpers so map keys built from those buffers are deterministic. The series also stops mutating the shared callchain object in the perf-event variants, passing length separately so the entry can stay const.