On Wed, Oct 28, 2026 at 05:35:48PM +0800, Feng Yang wrote:
> Sleepable BPF programs run under rcu_read_lock_trace(), not classic RCU.
> bpf_get_stack() relies on the caller holding a classic RCU read lock:
> get_perf_callchain() -> get_callchain_entry() dereferences
> callchain_cpus_entries, and the returned entry is read until
> callchain_store().  __bpf_get_stack() takes that lock only for the
> sleepable variant, i.e. when may_fault is true.

Hi Feng,

I hit the same root cause independently via syzbot and sent a fix a
few hours after yours, without having seen this patch -- sorry for the
overlap:

  https://lore.kernel.org/bpf/[email protected]/

It also covers the syzbot report for BPF_PROG_TYPE_SYSCALL programs
(always sleepable, run via bpf_prog_test_run_syscall() under
rcu_read_lock_trace() only), which reach bpf_get_stack_raw_tp() through
tracing_prog_func_proto():

  https://syzkaller.appspot.com/bug?extid=72a43cdb78469f7fbad1

The approach is different: instead of routing sleepable programs to new
sleepable protos, it simply takes rcu_read_lock() unconditionally in
__bpf_get_stack() around get_perf_callchain()/callchain_store(), as
Andrii suggested earlier that an extra nested rcu_read_lock() is
harmless:

  
https://lore.kernel.org/all/caef4bzyn33yqho-tsf8puwdmzoilaxkv+z1op6fjkbyocyc...@mail.gmail.com/

That is a 3+/6- change in kernel/bpf/stackmap.c, it covers every caller
of __bpf_get_stack() (including the tracepoint, raw_tp, iter and syscall
cases listed above), and since no helper gains might_sleep it does not
hold the per-CPU bpf_raw_tp_regs slot across a possible sleep in
callchain_finalize(), which is the issue the Sashiko review raised here.

It does not do what your patch additionally does, i.e. allow
BPF_F_USER_BUILD_ID to fault in build IDs from these program types.

I'm happy to go with whichever the maintainers prefer, or to drop mine.

Thanks,
Songsen

Reply via email to