Skip to content

Commit

Permalink
selftests/bpf: Add test for strict BTF type check
Browse files Browse the repository at this point in the history
Ensure that the edge case where first member type was matched
successfully even if it didn't match BTF type of register is caught and
rejected by the verifier.

Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>
Signed-off-by: Alexei Starovoitov <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
  • Loading branch information
kkdwivedi authored and Alexei Starovoitov committed Apr 26, 2022
1 parent 05a945d commit 792c0a3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
22 changes: 21 additions & 1 deletion net/bpf/test_run.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,13 @@ struct sock * noinline bpf_kfunc_call_test3(struct sock *sk)
return sk;
}

struct prog_test_member1 {
int a;
};

struct prog_test_member {
u64 c;
struct prog_test_member1 m;
int c;
};

struct prog_test_ref_kfunc {
Expand All @@ -576,6 +581,12 @@ bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr)
return &prog_test_struct;
}

noinline struct prog_test_member *
bpf_kfunc_call_memb_acquire(void)
{
return &prog_test_struct.memb;
}

noinline void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p)
{
}
Expand All @@ -584,6 +595,10 @@ noinline void bpf_kfunc_call_memb_release(struct prog_test_member *p)
{
}

noinline void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p)
{
}

noinline struct prog_test_ref_kfunc *
bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b)
{
Expand Down Expand Up @@ -673,8 +688,10 @@ BTF_ID(func, bpf_kfunc_call_test1)
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_memb_acquire)
BTF_ID(func, bpf_kfunc_call_test_release)
BTF_ID(func, bpf_kfunc_call_memb_release)
BTF_ID(func, bpf_kfunc_call_memb1_release)
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
BTF_ID(func, bpf_kfunc_call_test_pass_ctx)
BTF_ID(func, bpf_kfunc_call_test_pass1)
Expand All @@ -689,16 +706,19 @@ BTF_SET_END(test_sk_check_kfunc_ids)

BTF_SET_START(test_sk_acquire_kfunc_ids)
BTF_ID(func, bpf_kfunc_call_test_acquire)
BTF_ID(func, bpf_kfunc_call_memb_acquire)
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
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_ID(func, bpf_kfunc_call_memb1_release)
BTF_SET_END(test_sk_release_kfunc_ids)

BTF_SET_START(test_sk_ret_null_kfunc_ids)
BTF_ID(func, bpf_kfunc_call_test_acquire)
BTF_ID(func, bpf_kfunc_call_memb_acquire)
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
BTF_SET_END(test_sk_ret_null_kfunc_ids)

Expand Down
20 changes: 20 additions & 0 deletions tools/testing/selftests/bpf/verifier/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,26 @@
{ "bpf_kfunc_call_memb_release", 8 },
},
},
{
"calls: invalid kfunc call: don't match first member type when passed to release kfunc",
.insns = {
BPF_MOV64_IMM(BPF_REG_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_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 = "kernel function bpf_kfunc_call_memb1_release args#0 expected pointer",
.fixup_kfunc_btf_id = {
{ "bpf_kfunc_call_memb_acquire", 1 },
{ "bpf_kfunc_call_memb1_release", 5 },
},
},
{
"calls: invalid kfunc call: PTR_TO_BTF_ID with negative offset",
.insns = {
Expand Down

0 comments on commit 792c0a3

Please sign in to comment.