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
