Skip to content

Commit 7c036ed

Browse files
robertosassuAlexei Starovoitov
authored andcommitted
selftests/bpf: Add verifier tests for bpf_lookup_*_key() and bpf_key_put()
Add verifier tests for bpf_lookup_*_key() and bpf_key_put(), to ensure that acquired key references stored in the bpf_key structure are released, that a non-NULL bpf_key pointer is passed to bpf_key_put(), and that key references are not leaked. Also, slightly modify test_verifier.c, to find the BTF ID of the attach point for the LSM program type (currently, it is done only for TRACING). Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20220920075951.929132-11-roberto.sassu@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 94fd742 commit 7c036ed

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

tools/testing/selftests/bpf/config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ CONFIG_IPV6_GRE=y
3030
CONFIG_IPV6_SEG6_BPF=y
3131
CONFIG_IPV6_SIT=y
3232
CONFIG_IPV6_TUNNEL=y
33+
CONFIG_KEYS=y
3334
CONFIG_LIRC=y
3435
CONFIG_LWTUNNEL=y
3536
CONFIG_MPLS=y

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14981498
opts.log_level = DEFAULT_LIBBPF_LOG_LEVEL;
14991499
opts.prog_flags = pflags;
15001500

1501-
if (prog_type == BPF_PROG_TYPE_TRACING && test->kfunc) {
1501+
if ((prog_type == BPF_PROG_TYPE_TRACING ||
1502+
prog_type == BPF_PROG_TYPE_LSM) && test->kfunc) {
15021503
int attach_btf_id;
15031504

15041505
attach_btf_id = libbpf_find_vmlinux_btf_id(test->kfunc,

tools/testing/selftests/bpf/verifier/ref_tracking.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,145 @@
8484
.errstr = "Unreleased reference",
8585
.result = REJECT,
8686
},
87+
{
88+
"reference tracking: acquire/release user key reference",
89+
.insns = {
90+
BPF_MOV64_IMM(BPF_REG_1, -3),
91+
BPF_MOV64_IMM(BPF_REG_2, 0),
92+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
93+
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
94+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
95+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
96+
BPF_MOV64_IMM(BPF_REG_0, 0),
97+
BPF_EXIT_INSN(),
98+
},
99+
.prog_type = BPF_PROG_TYPE_LSM,
100+
.kfunc = "bpf",
101+
.expected_attach_type = BPF_LSM_MAC,
102+
.flags = BPF_F_SLEEPABLE,
103+
.fixup_kfunc_btf_id = {
104+
{ "bpf_lookup_user_key", 2 },
105+
{ "bpf_key_put", 5 },
106+
},
107+
.result = ACCEPT,
108+
},
109+
{
110+
"reference tracking: acquire/release system key reference",
111+
.insns = {
112+
BPF_MOV64_IMM(BPF_REG_1, 1),
113+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
114+
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
115+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
116+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
117+
BPF_MOV64_IMM(BPF_REG_0, 0),
118+
BPF_EXIT_INSN(),
119+
},
120+
.prog_type = BPF_PROG_TYPE_LSM,
121+
.kfunc = "bpf",
122+
.expected_attach_type = BPF_LSM_MAC,
123+
.flags = BPF_F_SLEEPABLE,
124+
.fixup_kfunc_btf_id = {
125+
{ "bpf_lookup_system_key", 1 },
126+
{ "bpf_key_put", 4 },
127+
},
128+
.result = ACCEPT,
129+
},
130+
{
131+
"reference tracking: release user key reference without check",
132+
.insns = {
133+
BPF_MOV64_IMM(BPF_REG_1, -3),
134+
BPF_MOV64_IMM(BPF_REG_2, 0),
135+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
136+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
137+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
138+
BPF_MOV64_IMM(BPF_REG_0, 0),
139+
BPF_EXIT_INSN(),
140+
},
141+
.prog_type = BPF_PROG_TYPE_LSM,
142+
.kfunc = "bpf",
143+
.expected_attach_type = BPF_LSM_MAC,
144+
.flags = BPF_F_SLEEPABLE,
145+
.errstr = "arg#0 pointer type STRUCT bpf_key must point to scalar, or struct with scalar",
146+
.fixup_kfunc_btf_id = {
147+
{ "bpf_lookup_user_key", 2 },
148+
{ "bpf_key_put", 4 },
149+
},
150+
.result = REJECT,
151+
},
152+
{
153+
"reference tracking: release system key reference without check",
154+
.insns = {
155+
BPF_MOV64_IMM(BPF_REG_1, 1),
156+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
157+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
158+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
159+
BPF_MOV64_IMM(BPF_REG_0, 0),
160+
BPF_EXIT_INSN(),
161+
},
162+
.prog_type = BPF_PROG_TYPE_LSM,
163+
.kfunc = "bpf",
164+
.expected_attach_type = BPF_LSM_MAC,
165+
.flags = BPF_F_SLEEPABLE,
166+
.errstr = "arg#0 pointer type STRUCT bpf_key must point to scalar, or struct with scalar",
167+
.fixup_kfunc_btf_id = {
168+
{ "bpf_lookup_system_key", 1 },
169+
{ "bpf_key_put", 3 },
170+
},
171+
.result = REJECT,
172+
},
173+
{
174+
"reference tracking: release with NULL key pointer",
175+
.insns = {
176+
BPF_MOV64_IMM(BPF_REG_1, 0),
177+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
178+
BPF_MOV64_IMM(BPF_REG_0, 0),
179+
BPF_EXIT_INSN(),
180+
},
181+
.prog_type = BPF_PROG_TYPE_LSM,
182+
.kfunc = "bpf",
183+
.expected_attach_type = BPF_LSM_MAC,
184+
.flags = BPF_F_SLEEPABLE,
185+
.errstr = "arg#0 pointer type STRUCT bpf_key must point to scalar, or struct with scalar",
186+
.fixup_kfunc_btf_id = {
187+
{ "bpf_key_put", 1 },
188+
},
189+
.result = REJECT,
190+
},
191+
{
192+
"reference tracking: leak potential reference to user key",
193+
.insns = {
194+
BPF_MOV64_IMM(BPF_REG_1, -3),
195+
BPF_MOV64_IMM(BPF_REG_2, 0),
196+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
197+
BPF_EXIT_INSN(),
198+
},
199+
.prog_type = BPF_PROG_TYPE_LSM,
200+
.kfunc = "bpf",
201+
.expected_attach_type = BPF_LSM_MAC,
202+
.flags = BPF_F_SLEEPABLE,
203+
.errstr = "Unreleased reference",
204+
.fixup_kfunc_btf_id = {
205+
{ "bpf_lookup_user_key", 2 },
206+
},
207+
.result = REJECT,
208+
},
209+
{
210+
"reference tracking: leak potential reference to system key",
211+
.insns = {
212+
BPF_MOV64_IMM(BPF_REG_1, 1),
213+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0, 0),
214+
BPF_EXIT_INSN(),
215+
},
216+
.prog_type = BPF_PROG_TYPE_LSM,
217+
.kfunc = "bpf",
218+
.expected_attach_type = BPF_LSM_MAC,
219+
.flags = BPF_F_SLEEPABLE,
220+
.errstr = "Unreleased reference",
221+
.fixup_kfunc_btf_id = {
222+
{ "bpf_lookup_system_key", 1 },
223+
},
224+
.result = REJECT,
225+
},
87226
{
88227
"reference tracking: release reference without check",
89228
.insns = {

0 commit comments

Comments
 (0)