linux/kernel
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
..
bpf bpf: Verify global subprogs in each sleepability context 2026-09-17 10:55:21 -07:00
cgroup cgroup: Fixes for v7.3-rc1 2026-08-31 14:20:32 -07:00
configs slab: support for compiler-assisted type-based slab cache partitioning 2026-05-14 10:44:09 +02:00
debug kgdb: update outdated references to kgdb_wait() 2026-04-21 16:41:54 +01:00
dma treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
entry entry: Rework trace_syscall_enter() 2026-07-20 20:38:40 +02:00
events Misc perf events fixes: 2026-09-06 11:06:09 -07:00
futex Misc locking fixes: 2026-09-06 10:45:46 -07:00
gcov Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
irq treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
kcsan kcsan: avoid unintended access checking in NMIs 2026-07-20 18:18:37 +02:00
livepatch livepatch: Fix NULL pointer dereference in klp_find_func() 2026-07-07 12:54:37 +02:00
liveupdate kho: make boot time huge page allocation work nicely with KHO 2026-08-23 09:17:38 -07:00
locking Misc locking fixes: 2026-09-06 10:45:46 -07:00
module module: validate string table section types 2026-08-06 16:44:45 +02:00
power PM: sleep: Allow disabling DPM watchdog by default 2026-07-23 15:46:34 +02:00
printk Merge branch 'for-7.3-console-registration-cleanup' into for-linus 2026-08-19 10:00:46 +02:00
rcu RCU updates: 2026-08-23 18:00:22 -07:00
sched Miscellaneous scheduler fixes: 2026-09-06 11:08:44 -07:00
time s390 updates for 7.3 merge window 2026-08-23 10:26:44 -07:00
trace tracing fixes for v7.3: 2026-09-06 14:21:24 -07:00
unwind Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
.gitignore kheaders: rebuild kheaders_data.tar.xz when a file is modified within a minute 2025-06-24 20:30:37 +09:00
acct.c fs: move SB_I_USERNS_VISIBLE to FS_USERNS_MOUNT_RESTRICTED 2026-05-11 23:13:01 +02:00
async.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
audit_fsnotify.c audit: fix recursive locking deadlock in audit_dupe_exe() 2026-05-27 19:15:34 -04:00
audit_tree.c audit: use 'unsigned int' instead of 'unsigned' 2026-05-26 17:15:30 -04:00
audit_watch.c audit: drop BUG_ON() from audit_add_to_parent() 2026-07-28 15:53:48 -04:00
audit.c audit: fix potential integer overflow in audit_log_n_string() 2026-07-29 16:19:06 -04:00
audit.h audit: fix recursive locking deadlock in audit_dupe_exe() 2026-05-27 19:15:34 -04:00
auditfilter.c audit/stable-7.3 PR 20260814 2026-08-19 16:21:32 -07:00
auditsc.c audit: drop BUG_ON() from audit_signal_info_syscall() 2026-07-28 15:53:49 -04:00
backtracetest.c
bounds.c x86/asm: Remove ANNOTATE_DATA_SPECIAL usage 2025-12-03 16:53:19 +01:00
capability.c capability: unexport has_capability_noaudit 2026-08-21 09:09:55 +02:00
cfi.c cfi: Move BPF CFI types and helpers to generic code 2025-07-31 18:23:53 -07:00
compat.c
configs.c
context_tracking.c context_tracking: Remove rcu_task_trace_heavyweight_{enter,exit}() 2026-01-01 16:39:46 +08:00
cpu_pm.c syscore: Pass context data to callbacks 2025-11-14 10:01:52 +01:00
cpu.c Misc CPU hotplug fixes: 2026-06-23 16:43:24 -07:00
crash_core_test.c crash: add KUnit tests for crash_exclude_mem_range 2025-09-13 17:32:55 -07:00
crash_core.c powerpc/kexec_file: Use crash_exclude_core_ranges() helper 2026-06-30 18:49:06 +03:00
crash_dump_dm_crypt.c crash_dump: release keyring reference at the correct time 2026-07-13 10:04:47 +03:00
crash_reserve.c kernel/crash: remove inclusion of crypto/sha1.h 2026-03-27 21:19:46 -07:00
cred.c exec_state: relocate dumpable information 2026-05-26 11:02:01 +02:00
delayacct.c sysctl: remove CONFIG_PROC_SYSCTL, it just mirrors CONFIG_SYSCTL 2026-08-05 15:28:23 +02:00
dma.c
elfcorehdr.c
exec_domain.c
exec_state.c exec_state: relocate dumpable information 2026-05-26 11:02:01 +02:00
exit.c Miscellaneous futex fixes: 2026-08-22 16:29:20 -07:00
exit.h
extable.c
fail_function.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
fork.c mm.git review status for master..mm-nonmm-stable 2026-08-23 08:07:11 -07:00
freezer.c freezer: Clarify that only cgroup1 freezer uses PM freezer 2025-10-30 20:10:27 +01:00
gen_kheaders.sh kheaders: make it possible to override TAR 2025-08-06 10:23:36 +09:00
groups.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
hung_task.c hung_task: explicitly report I/O wait state in log output 2026-03-27 21:19:40 -07:00
iomem.c
irq_work.c irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT 2026-05-11 16:28:04 +02:00
jump_label.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
kallsyms_internal.h kallsyms: Get rid of kallsyms relative base 2026-01-22 15:58:22 -07:00
kallsyms_selftest.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
kallsyms_selftest.h
kallsyms.c mm.git review status for linus..mm-nonmm-stable 2026-02-12 12:13:01 -08:00
kcmp.c fs: add real_fs to track task's actual fs_struct 2026-06-29 10:43:45 +02:00
Kconfig.freezer
Kconfig.hz
Kconfig.kexec liveupdate: kho: move to kernel/liveupdate 2025-11-27 14:24:33 -08:00
Kconfig.locks locking/qspinlock: Add contended_release tracepoint 2026-08-07 17:58:10 +02:00
Kconfig.preempt sched_ext: Changes for v7.3 2026-08-20 11:01:37 -07:00
kcov.c mm.git review status for master..mm-nonmm-stable 2026-08-23 08:07:11 -07:00
kexec_core.c liveupdate: skip serialization for context-preserving kexec 2026-06-01 09:19:38 +03:00
kexec_elf.c kexec: initialize ELF lowest address to ULONG_MAX 2025-03-16 22:30:47 -07:00
kexec_file.c kexec_file: skip checksum verification when safe 2026-07-01 13:01:08 +03:00
kexec_internal.h kexec: enable CMA based contiguous allocation 2025-08-02 12:01:38 -07:00
kexec.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
kheaders.c
kprobes.c kprobes: Protect kprobe_blacklist with RCU 2026-09-03 09:04:25 +09:00
kstack_erase.c sysctl: remove __user qualifier from stack_erasing_sysctl buffer argument 2025-11-27 15:44:53 +01:00
ksyms_common.c
ksysfs.c kernel: ksysfs: initialize kernel_kobj earlier 2026-04-03 19:39:52 +02:00
kthread.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
latencytop.c
Makefile exec: introduce struct task_exec_state 2026-05-26 11:02:01 +02:00
module_signature.c module: Give 'enum pkey_id_type' a more specific name 2026-03-24 21:42:37 +00:00
notifier.c
nscommon.c nsfs: tighten permission checks for ns iteration ioctls 2026-02-27 22:00:08 +01:00
nsproxy.c vfs-7.1-rc1.mount.v2 2026-04-14 19:59:25 -07:00
nstree.c nstree: tighten permission checks for listing 2026-02-27 22:00:11 +01:00
padata.c padata: Put CPU offline callback in ONLINE section to allow failure 2026-03-22 11:17:59 +09:00
panic.c bug/kunit: Core support for suppressing warning backtraces 2026-05-14 10:50:00 -06:00
params.c mm.git review status for master..mm-nonmm-stable 2026-08-23 08:07:11 -07:00
pid_namespace.c pid_namespace: allow opening pid_for_children before init was created 2026-03-20 14:44:26 +01:00
pid_sysctl.h
pid.c Summary 2026-08-20 08:46:41 -07:00
profile.c
ptrace.c exec_state: relocate dumpable information 2026-05-26 11:02:01 +02:00
range.c
reboot.c sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[] 2026-08-05 15:28:23 +02:00
regset.c
relay.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
resource_kunit.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
resource.c resource: downgrade "resource sanity check" warning to debug level 2026-08-03 21:10:05 -07:00
rseq.c rseq: Reenable performance optimizations conditionally 2026-05-06 17:40:27 +02:00
scftorture.c smp_call_function() torture-test updates: 2026-08-23 19:28:04 -07:00
scs.c scs: fix a wrong parameter in __scs_magic 2025-11-12 10:00:13 -08:00
seccomp.c seccomp, treewide: Rename and convert __secure_computing() to return boolean 2026-07-12 12:38:02 +02:00
signal.c signal: factor out the kernel reserved si_code check 2026-08-13 15:42:08 -07:00
smp.c SMP core updates: 2026-08-18 15:29:53 -07:00
smpboot.c sched/smp: Use the SMP version of idle_thread_set_boot_cpu() 2025-06-13 08:47:20 +02:00
smpboot.h
softirq.c interrupt: Disable interrupt before modifying hardirq_disable counter 2026-08-30 08:39:04 +02:00
stacktrace.c
static_call_inline.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
static_call.c
stop_machine.c stop_machine: Make stop_one_cpu_nowait() return void 2026-07-31 12:35:26 +02:00
sys_ni.c time: Respect COMPAT_32BIT_TIME for old time type functions 2026-07-07 23:52:53 +02:00
sys.c prctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminator 2026-08-19 19:55:05 -07:00
sysctl-test.c sysctl: move u8 register test to lib/test_sysctl.c 2025-04-14 14:13:41 +02:00
sysctl.c sysctl: remove CONFIG_PROC_SYSCTL, it just mirrors CONFIG_SYSCTL 2026-08-05 15:28:23 +02:00
task_work.c task_work: Fix NMI race condition 2025-10-29 10:29:54 +01:00
taskstats.c taskstats: fold the two cpumask handlers into one 2026-08-13 15:42:05 -07:00
torture.c torture: Don't leak shuffle_tmp_mask when shuffler kthread fails to start 2026-08-14 14:59:21 -07:00
tracepoint.c tracepoint: balance regfunc() on func_add() failure in tracepoint_add_func() 2026-04-14 05:17:02 -04:00
tsacct.c tsacct: skip all kernel threads 2026-01-26 19:07:13 -08:00
ucount.c binfmt_misc: correctly account pre-opened interpreters 2026-08-03 23:36:18 +02:00
uid16.c
uid16.h
umh.c fs: add umh argument to struct kernel_clone_args 2026-06-29 10:54:41 +02:00
up.c smp: Refactor remote CPU selection in smp_call_function_any() 2026-07-16 09:24:55 +02:00
user_namespace.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
user-return-notifier.c
user.c binfmt_misc: use RCU for the handler lookup 2026-08-03 10:08:36 +02:00
utsname_sysctl.c sysctl: remove CONFIG_PROC_SYSCTL, it just mirrors CONFIG_SYSCTL 2026-08-05 15:28:23 +02:00
utsname.c namespace-6.18-rc1 2025-09-29 11:20:29 -07:00
vhost_task.c vhost_task_create: kill unnecessary .exit_signal initialization 2026-06-10 02:17:00 -04:00
vmcore_info.c mm.git review status for linus..mm-nonmm-stable 2026-04-16 20:11:56 -07:00
watch_queue.c Convert 'alloc_flex' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
watchdog_buddy.c watchdog/hardlockup: improve buddy system detection timeliness 2026-03-27 21:19:47 -07:00
watchdog_perf.c watchdog/hardlockup: simplify perf event probe and remove per-cpu dependency 2026-02-08 00:13:35 -08:00
watchdog.c watchdog/softlockup: fix softlockup typos 2026-08-03 21:10:06 -07:00
workqueue_internal.h workqueue: Show in-flight work item duration in stall diagnostics 2026-03-05 07:27:48 -10:00
workqueue.c workqueue: Fixes for v7.3-rc1 2026-08-31 14:38:40 -07:00