On Tue, Aug 30, 2022 at 9:22 AM Roberto Sassu <roberto.sassu@xxxxxxxxxxxxxxx> wrote: > > From: Roberto Sassu <roberto.sassu@xxxxxxxxxx> > > Add verifier tests to ensure that only supported dynamic pointer types are > accepted, that the passed argument is actually a dynamic pointer, and that > the passed argument is a pointer to the stack. > > Signed-off-by: Roberto Sassu <roberto.sassu@xxxxxxxxxx> > --- > .../bpf/verifier/kfunc_dynptr_param.c | 72 +++++++++++++++++++ > 1 file changed, 72 insertions(+) > create mode 100644 tools/testing/selftests/bpf/verifier/kfunc_dynptr_param.c > > diff --git a/tools/testing/selftests/bpf/verifier/kfunc_dynptr_param.c b/tools/testing/selftests/bpf/verifier/kfunc_dynptr_param.c > new file mode 100644 > index 000000000000..8abb8d566321 > --- /dev/null > +++ b/tools/testing/selftests/bpf/verifier/kfunc_dynptr_param.c > @@ -0,0 +1,72 @@ > +{ > + "kfunc dynamic pointer param: type not supported", > + .insns = { > + BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), > + BPF_MOV64_REG(BPF_REG_6, BPF_REG_10), > + BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -16), > + BPF_LD_MAP_FD(BPF_REG_1, 0), > + BPF_MOV64_IMM(BPF_REG_2, 8), > + BPF_MOV64_IMM(BPF_REG_3, 0), > + BPF_MOV64_REG(BPF_REG_4, BPF_REG_6), > + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve_dynptr), > + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), > + BPF_MOV64_REG(BPF_REG_2, BPF_REG_6), > + BPF_MOV64_IMM(BPF_REG_3, 0), > + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), > + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), > + BPF_MOV64_IMM(BPF_REG_2, 0), > + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_discard_dynptr), > + BPF_MOV64_IMM(BPF_REG_0, 0), > + BPF_EXIT_INSN(), > + }, > + .fixup_map_ringbuf = { 3 }, > + .prog_type = BPF_PROG_TYPE_LSM, > + .kfunc = "bpf", > + .expected_attach_type = BPF_LSM_MAC, > + .flags = BPF_F_SLEEPABLE, > + .errstr = "arg#0 pointer type STRUCT bpf_dynptr_kern points to unsupported dynamic pointer type", > + .result = REJECT, > + .fixup_kfunc_btf_id = { > + { "bpf_verify_pkcs7_signature", 12 }, > + }, > +}, > +{ > + "kfunc dynamic pointer param: arg not a dynamic pointer", > + .insns = { > + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), > + BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), > + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), > + BPF_MOV64_REG(BPF_REG_2, BPF_REG_1), > + BPF_MOV64_IMM(BPF_REG_3, 0), > + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), > + BPF_EXIT_INSN(), > + }, > + .prog_type = BPF_PROG_TYPE_LSM, > + .kfunc = "bpf", > + .expected_attach_type = BPF_LSM_MAC, > + .flags = BPF_F_SLEEPABLE, > + .errstr = "arg#0 pointer type STRUCT bpf_dynptr_kern must be valid and initialized", > + .result = REJECT, > + .fixup_kfunc_btf_id = { > + { "bpf_verify_pkcs7_signature", 5 }, > + }, > +}, > +{ > + "kfunc dynamic pointer param: arg not a pointer to stack", > + .insns = { > + BPF_MOV64_IMM(BPF_REG_1, 0), > + BPF_MOV64_IMM(BPF_REG_2, 0), > + BPF_MOV64_IMM(BPF_REG_3, 0), > + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0), > + BPF_EXIT_INSN(), > + }, > + .prog_type = BPF_PROG_TYPE_LSM, > + .kfunc = "bpf", > + .expected_attach_type = BPF_LSM_MAC, > + .flags = BPF_F_SLEEPABLE, > + .errstr = "arg#0 pointer type STRUCT bpf_dynptr_kern not to stack", > + .result = REJECT, > + .fixup_kfunc_btf_id = { > + { "bpf_verify_pkcs7_signature", 3 }, > + }, > +}, Is this logic testable in plain C BPF code? I tend to side with Andrii [0] about finding these kinds of tests hard to maintain and read. [0] https://lore.kernel.org/bpf/CAEf4BzZJvr+vcO57TK94GM7B5=k2wPgAub4BBJf1Uz0xNpCPVg@xxxxxxxxxxxxxx/ > -- > 2.25.1 >