selftests/bpf: Add tests for kfunc register offset checks
Include a few verifier selftests that test against the problems being fixed by previous commits, i.e. release kfunc always require PTR_TO_BTF_ID fixed and var_off to be 0, and negative offset is not permitted and returns a helpful error message. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20220304224645.3677453-9-memxor@gmail.com
This commit is contained in:
Родитель
0b206c6d10
Коммит
8218ccb5bd
|
@ -270,9 +270,14 @@ struct sock * noinline bpf_kfunc_call_test3(struct sock *sk)
|
|||
return sk;
|
||||
}
|
||||
|
||||
struct prog_test_member {
|
||||
u64 c;
|
||||
};
|
||||
|
||||
struct prog_test_ref_kfunc {
|
||||
int a;
|
||||
int b;
|
||||
struct prog_test_member memb;
|
||||
struct prog_test_ref_kfunc *next;
|
||||
};
|
||||
|
||||
|
@ -295,6 +300,10 @@ noinline void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p)
|
|||
{
|
||||
}
|
||||
|
||||
noinline void bpf_kfunc_call_memb_release(struct prog_test_member *p)
|
||||
{
|
||||
}
|
||||
|
||||
struct prog_test_pass1 {
|
||||
int x0;
|
||||
struct {
|
||||
|
@ -379,6 +388,7 @@ BTF_ID(func, bpf_kfunc_call_test2)
|
|||
BTF_ID(func, bpf_kfunc_call_test3)
|
||||
BTF_ID(func, bpf_kfunc_call_test_acquire)
|
||||
BTF_ID(func, bpf_kfunc_call_test_release)
|
||||
BTF_ID(func, bpf_kfunc_call_memb_release)
|
||||
BTF_ID(func, bpf_kfunc_call_test_pass_ctx)
|
||||
BTF_ID(func, bpf_kfunc_call_test_pass1)
|
||||
BTF_ID(func, bpf_kfunc_call_test_pass2)
|
||||
|
@ -396,6 +406,7 @@ BTF_SET_END(test_sk_acquire_kfunc_ids)
|
|||
|
||||
BTF_SET_START(test_sk_release_kfunc_ids)
|
||||
BTF_ID(func, bpf_kfunc_call_test_release)
|
||||
BTF_ID(func, bpf_kfunc_call_memb_release)
|
||||
BTF_SET_END(test_sk_release_kfunc_ids)
|
||||
|
||||
BTF_SET_START(test_sk_ret_null_kfunc_ids)
|
||||
|
|
|
@ -115,6 +115,89 @@
|
|||
{ "bpf_kfunc_call_test_release", 5 },
|
||||
},
|
||||
},
|
||||
{
|
||||
"calls: invalid kfunc call: reg->off must be zero when passed to release kfunc",
|
||||
.insns = {
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||
.result = REJECT,
|
||||
.errstr = "R1 must have zero offset when passed to release func",
|
||||
.fixup_kfunc_btf_id = {
|
||||
{ "bpf_kfunc_call_test_acquire", 3 },
|
||||
{ "bpf_kfunc_call_memb_release", 8 },
|
||||
},
|
||||
},
|
||||
{
|
||||
"calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset",
|
||||
.insns = {
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 16),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -4),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||
.fixup_kfunc_btf_id = {
|
||||
{ "bpf_kfunc_call_test_acquire", 3 },
|
||||
{ "bpf_kfunc_call_test_release", 9 },
|
||||
},
|
||||
.result_unpriv = REJECT,
|
||||
.result = REJECT,
|
||||
.errstr = "negative offset ptr_ ptr R1 off=-4 disallowed",
|
||||
},
|
||||
{
|
||||
"calls: invalid kfunc call: PTR_TO_BTF_ID with variable offset",
|
||||
.insns = {
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
|
||||
BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
|
||||
BPF_JMP_IMM(BPF_JLE, BPF_REG_2, 4, 3),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 3),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
|
||||
.fixup_kfunc_btf_id = {
|
||||
{ "bpf_kfunc_call_test_acquire", 3 },
|
||||
{ "bpf_kfunc_call_test_release", 9 },
|
||||
{ "bpf_kfunc_call_test_release", 13 },
|
||||
{ "bpf_kfunc_call_test_release", 17 },
|
||||
},
|
||||
.result_unpriv = REJECT,
|
||||
.result = REJECT,
|
||||
.errstr = "variable ptr_ access var_off=(0x0; 0x7) disallowed",
|
||||
},
|
||||
{
|
||||
"calls: basic sanity",
|
||||
.insns = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче