mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-03 23:37:40 -04:00
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>
This commit is contained in:
committed by
Alexei Starovoitov
parent
6c2128505f
commit
a1e5c46eae
@@ -9,6 +9,10 @@
|
||||
|
||||
extern void bpf_rcu_read_lock(void) __ksym;
|
||||
extern void bpf_rcu_read_unlock(void) __ksym;
|
||||
extern void bpf_preempt_disable(void) __ksym;
|
||||
extern void bpf_preempt_enable(void) __ksym;
|
||||
extern void bpf_local_irq_save(unsigned long *) __ksym;
|
||||
extern void bpf_local_irq_restore(unsigned long *) __ksym;
|
||||
|
||||
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
|
||||
|
||||
@@ -349,4 +353,47 @@ int reject_exception_throw_cb_diff(struct __sk_buff *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline static int always_throws(void)
|
||||
{
|
||||
bpf_throw(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline static int rcu_lock_then_throw(void)
|
||||
{
|
||||
bpf_rcu_read_lock();
|
||||
bpf_throw(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("?tc")
|
||||
__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region")
|
||||
int reject_subprog_rcu_lock_throw(void *ctx)
|
||||
{
|
||||
rcu_lock_then_throw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("?tc")
|
||||
__failure __msg("bpf_throw cannot be used inside bpf_preempt_disable-ed region")
|
||||
int reject_subprog_throw_preempt_lock(void *ctx)
|
||||
{
|
||||
bpf_preempt_disable();
|
||||
always_throws();
|
||||
bpf_preempt_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("?tc")
|
||||
__failure __msg("bpf_throw cannot be used inside bpf_local_irq_save-ed region")
|
||||
int reject_subprog_throw_irq_lock(void *ctx)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
bpf_local_irq_save(&flags);
|
||||
always_throws();
|
||||
bpf_local_irq_restore(&flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
||||
Reference in New Issue
Block a user