selftests/bpf: Add test for static subprog call in lock cs
Add selftests for static subprog calls within bpf_spin_lock critical section, and ensure we still reject global subprog calls. Also test the case where a subprog call will unlock the caller's held lock, or the caller will unlock a lock taken by a subprog call, ensuring correct transfer of lock state across frames on exit. Acked-by: Yonghong Song <yonghong.song@linux.dev> Acked-by: David Vernet <void@manifault.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20240204222349.938118-3-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
a44b1334aa
commit
e8699c4ff8
@ -48,6 +48,8 @@ static struct {
|
||||
{ "lock_id_mismatch_innermapval_kptr", "bpf_spin_unlock of different lock" },
|
||||
{ "lock_id_mismatch_innermapval_global", "bpf_spin_unlock of different lock" },
|
||||
{ "lock_id_mismatch_innermapval_mapval", "bpf_spin_unlock of different lock" },
|
||||
{ "lock_global_subprog_call1", "global function calls are not allowed while holding a lock" },
|
||||
{ "lock_global_subprog_call2", "global function calls are not allowed while holding a lock" },
|
||||
};
|
||||
|
||||
static int match_regex(const char *pattern, const char *string)
|
||||
|
@ -101,4 +101,69 @@ int bpf_spin_lock_test(struct __sk_buff *skb)
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
struct bpf_spin_lock lockA __hidden SEC(".data.A");
|
||||
|
||||
__noinline
|
||||
static int static_subprog(struct __sk_buff *ctx)
|
||||
{
|
||||
volatile int ret = 0;
|
||||
|
||||
if (ctx->protocol)
|
||||
return ret;
|
||||
return ret + ctx->len;
|
||||
}
|
||||
|
||||
__noinline
|
||||
static int static_subprog_lock(struct __sk_buff *ctx)
|
||||
{
|
||||
volatile int ret = 0;
|
||||
|
||||
ret = static_subprog(ctx);
|
||||
bpf_spin_lock(&lockA);
|
||||
return ret + ctx->len;
|
||||
}
|
||||
|
||||
__noinline
|
||||
static int static_subprog_unlock(struct __sk_buff *ctx)
|
||||
{
|
||||
volatile int ret = 0;
|
||||
|
||||
ret = static_subprog(ctx);
|
||||
bpf_spin_unlock(&lockA);
|
||||
return ret + ctx->len;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int lock_static_subprog_call(struct __sk_buff *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
bpf_spin_lock(&lockA);
|
||||
if (ctx->mark == 42)
|
||||
ret = static_subprog(ctx);
|
||||
bpf_spin_unlock(&lockA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int lock_static_subprog_lock(struct __sk_buff *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = static_subprog_lock(ctx);
|
||||
bpf_spin_unlock(&lockA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int lock_static_subprog_unlock(struct __sk_buff *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
bpf_spin_lock(&lockA);
|
||||
ret = static_subprog_unlock(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
@ -201,4 +201,48 @@ CHECK(innermapval_mapval, &iv->lock, &v->lock);
|
||||
|
||||
#undef CHECK
|
||||
|
||||
__noinline
|
||||
int global_subprog(struct __sk_buff *ctx)
|
||||
{
|
||||
volatile int ret = 0;
|
||||
|
||||
if (ctx->protocol)
|
||||
ret += ctx->protocol;
|
||||
return ret + ctx->mark;
|
||||
}
|
||||
|
||||
__noinline
|
||||
static int static_subprog_call_global(struct __sk_buff *ctx)
|
||||
{
|
||||
volatile int ret = 0;
|
||||
|
||||
if (ctx->protocol)
|
||||
return ret;
|
||||
return ret + ctx->len + global_subprog(ctx);
|
||||
}
|
||||
|
||||
SEC("?tc")
|
||||
int lock_global_subprog_call1(struct __sk_buff *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
bpf_spin_lock(&lockA);
|
||||
if (ctx->mark == 42)
|
||||
ret = global_subprog(ctx);
|
||||
bpf_spin_unlock(&lockA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SEC("?tc")
|
||||
int lock_global_subprog_call2(struct __sk_buff *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
bpf_spin_lock(&lockA);
|
||||
if (ctx->mark == 42)
|
||||
ret = static_subprog_call_global(ctx);
|
||||
bpf_spin_unlock(&lockA);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
Loading…
x
Reference in New Issue
Block a user