summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorNing Ding <dingning04@gmail.com>2026-08-05 16:39:33 -0700
committerKumar Kartikeya Dwivedi <memxor@gmail.com>2026-08-06 15:46:43 +0200
commitd65739bf93be5160c1e0af00064874bbe262d5b6 (patch)
treeaba6421ef0054537a2d66515aefb898148cb4b30 /tools
parent7d008cde75c07713cf5bb9371d187a0ad3a37a4c (diff)
downloadlinux-next-d65739bf93be5160c1e0af00064874bbe262d5b6.tar.gz
linux-next-d65739bf93be5160c1e0af00064874bbe262d5b6.zip
bpf: Account for preempt and IRQ state in RCU protection
Disabling preemption or local IRQs keeps the current CPU in an RCU read-side critical section, but in_rcu_cs() does not account for either state. The verifier therefore rejects safe kptr accesses and invalidates pointers when another RCU source ends. Include preemption-disabled and IRQ-disabled state in in_rcu_cs(). Invalidate RCU-protected pointers on RCU unlock, preempt enable, or IRQ restore only after the final protection ends. Signed-off-by: Ning Ding <dingning04@gmail.com> Link: https://lore.kernel.org/bpf/20260805233940.3966981-2-dingning04@gmail.com [ kkd: Simplify was_in_rcu_cs on spin unlock and adjust the selftest. ] Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/progs/cpumask_failure.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/tools/testing/selftests/bpf/progs/cpumask_failure.c b/tools/testing/selftests/bpf/progs/cpumask_failure.c
index 74b4cd4bcdbb..4628feb53d86 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_failure.c
+++ b/tools/testing/selftests/bpf/progs/cpumask_failure.c
@@ -116,9 +116,9 @@ int BPF_PROG(test_cpumask_null, struct task_struct *task, u64 clone_flags)
return 0;
}
-SEC("tp_btf/task_newtask")
+SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
__failure __msg("R2 must be a rcu pointer")
-int BPF_PROG(test_global_mask_out_of_rcu, struct task_struct *task, u64 clone_flags)
+int BPF_PROG(test_global_mask_out_of_rcu)
{
struct bpf_cpumask *local, *prev;
@@ -133,6 +133,10 @@ int BPF_PROG(test_global_mask_out_of_rcu, struct task_struct *task, u64 clone_fl
return 0;
}
+ /*
+ * Use a sleepable program so explicit RCU is the only source of RCU
+ * protection.
+ */
bpf_rcu_read_lock();
local = global_mask;
if (!local) {