Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/bpf: Add tests for bpf_throw lock leak from subprogs

Add test cases to ensure the verifier correctly rejects bpf_throw from
subprogs when RCU, preempt, or IRQ locks are held:

* reject_subprog_rcu_lock_throw: subprog acquires bpf_rcu_read_lock and
then calls bpf_throw
* reject_subprog_throw_preempt_lock: always-throwing subprog called while
caller holds bpf_preempt_disable
* reject_subprog_throw_irq_lock: always-throwing subprog called while
caller holds bpf_local_irq_save

Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260320000809.643798-2-ihor.solodrai@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Ihor Solodrai and committed by
Alexei Starovoitov
a1e5c46e 6c212850

+47
+47
tools/testing/selftests/bpf/progs/exceptions_fail.c
··· 9 9 10 10 extern void bpf_rcu_read_lock(void) __ksym; 11 11 extern void bpf_rcu_read_unlock(void) __ksym; 12 + extern void bpf_preempt_disable(void) __ksym; 13 + extern void bpf_preempt_enable(void) __ksym; 14 + extern void bpf_local_irq_save(unsigned long *) __ksym; 15 + extern void bpf_local_irq_restore(unsigned long *) __ksym; 12 16 13 17 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8))) 14 18 ··· 350 346 bpf_loop(5, loop_cb1, NULL, 0); 351 347 else 352 348 bpf_loop(5, loop_cb2, NULL, 0); 349 + return 0; 350 + } 351 + 352 + __noinline static int always_throws(void) 353 + { 354 + bpf_throw(0); 355 + return 0; 356 + } 357 + 358 + __noinline static int rcu_lock_then_throw(void) 359 + { 360 + bpf_rcu_read_lock(); 361 + bpf_throw(0); 362 + return 0; 363 + } 364 + 365 + SEC("?tc") 366 + __failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region") 367 + int reject_subprog_rcu_lock_throw(void *ctx) 368 + { 369 + rcu_lock_then_throw(); 370 + return 0; 371 + } 372 + 373 + SEC("?tc") 374 + __failure __msg("bpf_throw cannot be used inside bpf_preempt_disable-ed region") 375 + int reject_subprog_throw_preempt_lock(void *ctx) 376 + { 377 + bpf_preempt_disable(); 378 + always_throws(); 379 + bpf_preempt_enable(); 380 + return 0; 381 + } 382 + 383 + SEC("?tc") 384 + __failure __msg("bpf_throw cannot be used inside bpf_local_irq_save-ed region") 385 + int reject_subprog_throw_irq_lock(void *ctx) 386 + { 387 + unsigned long flags; 388 + 389 + bpf_local_irq_save(&flags); 390 + always_throws(); 391 + bpf_local_irq_restore(&flags); 353 392 return 0; 354 393 } 355 394