linux/kernel/bpf
Kumar Kartikeya Dwivedi 40c2096961 bpf: Verify global subprogs in each sleepability context
Global subprograms are verified independently with a fresh verifier root.
do_check_common() currently seeds that root's in_sleepable state from the
program, even though a global subprogram can also run from callbacks whose
execution context differs from the program's main entry point.

In particular, workqueue and task-work callbacks are sleepable even when
the containing program is not. A global subprogram of that program is
therefore verified as non-sleepable, making in_rcu_cs() true and allowing
loads of RCU-protected kptrs to produce trusted MEM_RCU pointers. The same
subprogram can then be called from a sleepable callback without a classic
RCU reader. It can retain such a pointer while the object is freed and use
it after free.

The verifier's execution-context predicates are complementary. A state is
sleepable only when in_sleepable is set and no RCU, preemption, IRQ, or lock
region is active. Each condition which prevents sleeping also provides RCU
protection, while in_rcu_cs() treats a non-sleepable state as implicitly
protected.

Use this relationship to represent a global subprogram caller with only the
result of in_sleepable_context(). A protected sleepable caller is normalized
to in_sleepable=false at the independent verification root. This both
prevents sleepable operations and makes in_rcu_cs() true without copying
caller-owned lock state.

Track only the contexts in which each global subprogram is actually
reached. Verify it once if all reachable calls use the same context, and
twice only if both sleepable and non-sleepable calls reach it. Calls found
while verifying globals or asynchronous callbacks mark further contexts
for checking. Repeat the existing subprogram walk until all called
contexts have been verified; unreachable global calls remain unchecked.

Accumulate instruction counts over those verification passes. Preserve
the total recorded before each pass, since path accounting has already
added this pass's synchronous instructions and its root total must also
include asynchronous subprograms.

This makes an unprotected callback verify the global subprogram as
sleepable, turning its RCU-protected kptr load into an untrusted pointer.
Protected callers and global subprograms which do not depend on implicit RCU
protection remain valid.

Fixes: 81f1d7a583 ("bpf: wq: add bpf_wq_set_callback_impl")
Fixes: 38aa7003e3 ("bpf: task work scheduling kfuncs")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260914131923.2544250-2-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-09-17 10:55:21 -07:00
..
preload umd: Remove usermode driver framework 2025-07-26 21:03:04 +02:00
arena.c bpf: Mark existing lock-safe kfuncs with KF_SPINLOCK_SAFE 2026-08-06 10:58:04 +02:00
arraymap.c bpf: Fix percpu map update indexing with sparse CPU IDs 2026-08-21 10:41:27 -07:00
backtrack.c bpf: backtracking shouldn't clear outer frame R1-R5 for callbacks 2026-09-02 11:13:21 -07:00
bloom_filter.c bpf: Harden bloom filter sizing and indexing on 32-bit kernels 2026-08-05 11:45:20 -07:00
bpf_cgrp_storage.c bpf: Remove gfp_flags plumbing from bpf_local_storage_update() 2026-04-10 21:22:32 -07:00
bpf_inode_storage.c bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized 2026-06-30 16:31:56 +02:00
bpf_insn_array.c bpf: Lose const-ness of map in map_check_btf() 2026-02-27 15:39:00 -08:00
bpf_iter.c bpf: Reject non-scalar bpf_loop iteration counts 2026-09-05 20:50:13 -07:00
bpf_local_storage.c bpf: Remove gfp_flags plumbing from bpf_local_storage_update() 2026-04-10 21:22:32 -07:00
bpf_lru_list.c bpf: Fix NMI/tracepoint re-entry deadlock on lru locks 2026-06-07 18:46:13 -07:00
bpf_lru_list.h bpf: Fix NMI/tracepoint re-entry deadlock on lru locks 2026-06-07 18:46:13 -07:00
bpf_lsm_proto.c bpf: annotate file argument as __nullable in bpf_lsm_mmap_file 2025-12-21 10:56:33 -08:00
bpf_lsm.c bpf: Rename ARG_CONST_SIZE{,_OR_ZERO} to ARG_MEM_SIZE{,_OR_ZERO} 2026-08-03 00:29:14 +02:00
bpf_struct_ops.c bpf: Support __arena and __arena__nullable on struct_ops arguments 2026-08-08 03:03:26 -07:00
bpf_task_storage.c bpf: Remove gfp_flags plumbing from bpf_local_storage_update() 2026-04-10 21:22:32 -07:00
btf_iter.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
btf_relocate.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
btf.c bpf: Fix divide-by-zero in btf_struct_walk() 2026-09-10 16:58:05 -07:00
cfg.c bpf: don't rewrite bpf_fastcall patterns entered by a jump 2026-09-03 18:55:40 -07:00
cgroup_iter.c bpf: add new BPF_CGROUP_ITER_CHILDREN control option 2026-01-27 09:05:54 -08:00
cgroup.c bpf: Reject negative optlen in cgroup getsockopt hook 2026-08-17 11:33:29 +02:00
check_btf.c bpf: Rename 'early' BTF checking as a preparation phase 2026-08-08 03:03:25 -07:00
cnum_defs.h bpf: Export cnum_umin/umax() helpers for netronome driver 2026-04-27 10:09:48 -07:00
cnum.c bpf: representation and basic operations on circular numbers 2026-04-24 18:14:17 -07:00
const_fold.c bpf: Introduce global percpu data 2026-08-13 10:27:40 -07:00
core.c x86/bpf: Make arch_bpf_trampoline_size allocate from EXECMEM_MODULE_DATA 2026-08-20 17:52:31 +02:00
cpumap.c bpf: Add missing XDP_ABORTED handling in cpumap 2026-03-03 08:37:21 -08:00
cpumask.c bpf: Require a BPF cpumask for bpf_cpumask_populate() 2026-07-12 01:52:36 +02:00
crypto.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
devmap.c bpf: Run generic devmap egress prog on private skb 2026-06-12 18:21:01 -07:00
diagnostics.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
diagnostics.h bpf: Report Policy helper and kfunc errors 2026-08-15 11:15:17 -07:00
disasm.c bpf: update disasm.c to print BPF_PROBE_ATOMIC as atomics 2026-09-03 18:54:45 -07:00
disasm.h
dispatcher.c bpf: dispatcher: Allocate bpf_dispatcher->rw_image with vzalloc() 2026-07-22 17:26:39 +02:00
dmabuf_iter.c bpf: Fix truncated dmabuf iterator reads 2025-12-09 23:48:34 -08:00
fixups.c bpf: zero extend the result of an arena 32-bit cmpxchg 2026-09-03 18:54:45 -07:00
hashtab.c bpf: Fix u32 overflow issue in map batch operations 2026-09-13 21:58:40 -07:00
helpers.c bpf: Require CAP_PERFMON for kfuncs reading memory 2026-09-10 16:55:47 -07:00
inode.c bpf-next-7.2 2026-06-17 09:18:14 +01:00
Kconfig bpf: Update the bpf_prog_calc_tag to use SHA256 2025-09-18 19:10:20 -07:00
kmem_cache_iter.c bpf: Add open coded version of kmem_cache iterator 2024-11-01 11:08:32 -07:00
link_iter.c bpf: Clean up individual BTF_ID code 2025-07-16 18:34:42 -07:00
liveness.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
local_storage.c bpf: Fix percpu map update indexing with sparse CPU IDs 2026-08-21 10:41:27 -07:00
log.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
lpm_trie.c bpf: Allow LPM map access from sleepable BPF programs 2026-06-09 12:42:22 -07:00
Makefile bpf: Add verifier diagnostics report helpers 2026-08-15 11:11:16 -07:00
map_in_map.c bpf: Reject exclusive maps as inner maps in map-in-map 2026-06-01 18:36:40 -07:00
map_in_map.h bpf: Add map and need_defer parameters to .map_fd_put_ptr() 2023-12-04 17:50:26 -08:00
map_iter.c bpf: Implement iteration ops for resizable hashtab 2026-06-05 08:00:08 -07:00
memalloc.c bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk 2026-09-13 19:37:20 -07:00
mmap_unlock_work.h bpf: Fix mmap_lock leak in irq_work path 2026-08-08 10:25:36 +02:00
mprog.c bpf: Handle bpf_mprog_query with NULL entry 2023-10-06 17:11:20 -07:00
net_namespace.c bpf: Fix potential UAF in bpf_netns_link_update_prog 2026-07-30 15:28:46 -07:00
offload.c bpf: Fix use-after-free in offloaded map/prog info fill 2026-04-09 13:24:32 -07:00
percpu_freelist.c bpf: Fix infinite loop in pcpu_freelist push with one possible CPU 2026-08-20 20:44:16 +02:00
percpu_freelist.h bpf: Fix infinite loop in pcpu_freelist push with one possible CPU 2026-08-20 20:44:16 +02:00
prog_iter.c bpf: Clean up individual BTF_ID code 2025-07-16 18:34:42 -07:00
queue_stack_maps.c bpf: Drop duplicate blank lines in kernel/bpf/ 2026-08-13 10:27:40 -07:00
range_tree.c bpf: arena: Reintroduce memcg accounting 2026-01-02 14:31:59 -08:00
range_tree.h bpf: Introduce range_tree data structure and use it in bpf arena 2024-11-13 13:52:45 -08:00
relo_core.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
reuseport_array.c bpf: Use sockfd_put() helper 2024-08-30 08:57:47 -07:00
ringbuf.c bpf: Fix available-data accounting on 32-bit wrap in overwrite mode 2026-08-14 15:20:37 -07:00
rqspinlock.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.2-rc7 2026-08-07 23:04:17 +02:00
rqspinlock.h rqspinlock: Protect waiters in queue from stalls 2025-03-19 08:03:05 -07:00
stackmap.c bpf: Mark faultable stack helpers as sleepable 2026-09-03 19:22:52 -07:00
states.c bpf: don't downgrade half-dead scalar zero spills to STACK_ZERO 2026-08-28 10:44:21 -07:00
stream.c bpf: Add bpf_stream_print_stack stack dumping kfunc 2026-02-03 10:41:16 -08:00
syscall.c bpf: Fix u32 overflow issue in map batch operations 2026-09-13 21:58:40 -07:00
sysfs_btf.c Driver core changes for 6.17-rc1 2025-07-29 12:15:39 -07:00
task_iter.c bpf: Fix mmap_lock leak in irq_work path 2026-08-08 10:25:36 +02:00
tcx.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
tnum.c bpf: Simplify tnum_step() 2026-03-24 08:45:29 -07:00
token.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
trampoline.c bpf: Make bpf_trampoline_multi_detach return void 2026-08-13 02:52:23 +02:00
verifier.c bpf: Verify global subprogs in each sleepability context 2026-09-17 10:55:21 -07:00