Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
fork
Configure Feed
Select the types of activity you want to include in your feed.
1{
2 "reference tracking: leak potential reference",
3 .insns = {
4 BPF_SK_LOOKUP(sk_lookup_tcp),
5 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), /* leak reference */
6 BPF_EXIT_INSN(),
7 },
8 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9 .errstr = "Unreleased reference",
10 .result = REJECT,
11},
12{
13 "reference tracking: leak potential reference to sock_common",
14 .insns = {
15 BPF_SK_LOOKUP(skc_lookup_tcp),
16 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), /* leak reference */
17 BPF_EXIT_INSN(),
18 },
19 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
20 .errstr = "Unreleased reference",
21 .result = REJECT,
22},
23{
24 "reference tracking: leak potential reference on stack",
25 .insns = {
26 BPF_SK_LOOKUP(sk_lookup_tcp),
27 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
28 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
29 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
30 BPF_MOV64_IMM(BPF_REG_0, 0),
31 BPF_EXIT_INSN(),
32 },
33 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
34 .errstr = "Unreleased reference",
35 .result = REJECT,
36},
37{
38 "reference tracking: leak potential reference on stack 2",
39 .insns = {
40 BPF_SK_LOOKUP(sk_lookup_tcp),
41 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
42 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
43 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
44 BPF_MOV64_IMM(BPF_REG_0, 0),
45 BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
46 BPF_EXIT_INSN(),
47 },
48 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
49 .errstr = "Unreleased reference",
50 .result = REJECT,
51},
52{
53 "reference tracking: zero potential reference",
54 .insns = {
55 BPF_SK_LOOKUP(sk_lookup_tcp),
56 BPF_MOV64_IMM(BPF_REG_0, 0), /* leak reference */
57 BPF_EXIT_INSN(),
58 },
59 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
60 .errstr = "Unreleased reference",
61 .result = REJECT,
62},
63{
64 "reference tracking: zero potential reference to sock_common",
65 .insns = {
66 BPF_SK_LOOKUP(skc_lookup_tcp),
67 BPF_MOV64_IMM(BPF_REG_0, 0), /* leak reference */
68 BPF_EXIT_INSN(),
69 },
70 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
71 .errstr = "Unreleased reference",
72 .result = REJECT,
73},
74{
75 "reference tracking: copy and zero potential references",
76 .insns = {
77 BPF_SK_LOOKUP(sk_lookup_tcp),
78 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
79 BPF_MOV64_IMM(BPF_REG_0, 0),
80 BPF_MOV64_IMM(BPF_REG_7, 0), /* leak reference */
81 BPF_EXIT_INSN(),
82 },
83 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
84 .errstr = "Unreleased reference",
85 .result = REJECT,
86},
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 is ptr_or_null_ expected ptr_ or socket",
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 is ptr_or_null_ expected ptr_ or socket",
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},
226{
227 "reference tracking: release reference without check",
228 .insns = {
229 BPF_SK_LOOKUP(sk_lookup_tcp),
230 /* reference in r0 may be NULL */
231 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
232 BPF_MOV64_IMM(BPF_REG_2, 0),
233 BPF_EMIT_CALL(BPF_FUNC_sk_release),
234 BPF_EXIT_INSN(),
235 },
236 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
237 .errstr = "type=sock_or_null expected=sock",
238 .result = REJECT,
239},
240{
241 "reference tracking: release reference to sock_common without check",
242 .insns = {
243 BPF_SK_LOOKUP(skc_lookup_tcp),
244 /* reference in r0 may be NULL */
245 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
246 BPF_MOV64_IMM(BPF_REG_2, 0),
247 BPF_EMIT_CALL(BPF_FUNC_sk_release),
248 BPF_EXIT_INSN(),
249 },
250 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
251 .errstr = "type=sock_common_or_null expected=sock",
252 .result = REJECT,
253},
254{
255 "reference tracking: release reference",
256 .insns = {
257 BPF_SK_LOOKUP(sk_lookup_tcp),
258 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
259 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
260 BPF_EMIT_CALL(BPF_FUNC_sk_release),
261 BPF_EXIT_INSN(),
262 },
263 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
264 .result = ACCEPT,
265},
266{
267 "reference tracking: release reference to sock_common",
268 .insns = {
269 BPF_SK_LOOKUP(skc_lookup_tcp),
270 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
271 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
272 BPF_EMIT_CALL(BPF_FUNC_sk_release),
273 BPF_EXIT_INSN(),
274 },
275 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
276 .result = ACCEPT,
277},
278{
279 "reference tracking: release reference 2",
280 .insns = {
281 BPF_SK_LOOKUP(sk_lookup_tcp),
282 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
283 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
284 BPF_EXIT_INSN(),
285 BPF_EMIT_CALL(BPF_FUNC_sk_release),
286 BPF_EXIT_INSN(),
287 },
288 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
289 .result = ACCEPT,
290},
291{
292 "reference tracking: release reference twice",
293 .insns = {
294 BPF_SK_LOOKUP(sk_lookup_tcp),
295 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
296 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
297 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
298 BPF_EMIT_CALL(BPF_FUNC_sk_release),
299 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
300 BPF_EMIT_CALL(BPF_FUNC_sk_release),
301 BPF_EXIT_INSN(),
302 },
303 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
304 .errstr = "type=scalar expected=sock",
305 .result = REJECT,
306},
307{
308 "reference tracking: release reference twice inside branch",
309 .insns = {
310 BPF_SK_LOOKUP(sk_lookup_tcp),
311 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
312 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
313 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), /* goto end */
314 BPF_EMIT_CALL(BPF_FUNC_sk_release),
315 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
316 BPF_EMIT_CALL(BPF_FUNC_sk_release),
317 BPF_EXIT_INSN(),
318 },
319 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
320 .errstr = "type=scalar expected=sock",
321 .result = REJECT,
322},
323{
324 "reference tracking: alloc, check, free in one subbranch",
325 .insns = {
326 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
327 offsetof(struct __sk_buff, data)),
328 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
329 offsetof(struct __sk_buff, data_end)),
330 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
331 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
332 /* if (offsetof(skb, mark) > data_len) exit; */
333 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
334 BPF_EXIT_INSN(),
335 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
336 offsetof(struct __sk_buff, mark)),
337 BPF_SK_LOOKUP(sk_lookup_tcp),
338 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 1), /* mark == 0? */
339 /* Leak reference in R0 */
340 BPF_EXIT_INSN(),
341 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
342 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
343 BPF_EMIT_CALL(BPF_FUNC_sk_release),
344 BPF_EXIT_INSN(),
345 },
346 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
347 .errstr = "Unreleased reference",
348 .result = REJECT,
349 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
350},
351{
352 "reference tracking: alloc, check, free in both subbranches",
353 .insns = {
354 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
355 offsetof(struct __sk_buff, data)),
356 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
357 offsetof(struct __sk_buff, data_end)),
358 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
359 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
360 /* if (offsetof(skb, mark) > data_len) exit; */
361 BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
362 BPF_EXIT_INSN(),
363 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
364 offsetof(struct __sk_buff, mark)),
365 BPF_SK_LOOKUP(sk_lookup_tcp),
366 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 4), /* mark == 0? */
367 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
368 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
369 BPF_EMIT_CALL(BPF_FUNC_sk_release),
370 BPF_EXIT_INSN(),
371 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
372 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
373 BPF_EMIT_CALL(BPF_FUNC_sk_release),
374 BPF_EXIT_INSN(),
375 },
376 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
377 .result = ACCEPT,
378 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
379},
380{
381 "reference tracking in call: free reference in subprog",
382 .insns = {
383 BPF_SK_LOOKUP(sk_lookup_tcp),
384 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
385 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
386 BPF_MOV64_IMM(BPF_REG_0, 0),
387 BPF_EXIT_INSN(),
388
389 /* subprog 1 */
390 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
391 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
392 BPF_EMIT_CALL(BPF_FUNC_sk_release),
393 BPF_EXIT_INSN(),
394 },
395 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
396 .result = ACCEPT,
397},
398{
399 "reference tracking in call: free reference in subprog and outside",
400 .insns = {
401 BPF_SK_LOOKUP(sk_lookup_tcp),
402 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
403 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
404 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
405 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
406 BPF_EMIT_CALL(BPF_FUNC_sk_release),
407 BPF_EXIT_INSN(),
408
409 /* subprog 1 */
410 BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
411 BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
412 BPF_EMIT_CALL(BPF_FUNC_sk_release),
413 BPF_EXIT_INSN(),
414 },
415 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
416 .errstr = "type=scalar expected=sock",
417 .result = REJECT,
418},
419{
420 "reference tracking in call: alloc & leak reference in subprog",
421 .insns = {
422 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
423 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
424 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
425 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
426 BPF_MOV64_IMM(BPF_REG_0, 0),
427 BPF_EXIT_INSN(),
428
429 /* subprog 1 */
430 BPF_MOV64_REG(BPF_REG_6, BPF_REG_4),
431 BPF_SK_LOOKUP(sk_lookup_tcp),
432 /* spill unchecked sk_ptr into stack of caller */
433 BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
434 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
435 BPF_EXIT_INSN(),
436 },
437 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
438 .errstr = "Unreleased reference",
439 .result = REJECT,
440},
441{
442 "reference tracking in call: alloc in subprog, release outside",
443 .insns = {
444 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
445 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
446 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
447 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
448 BPF_EMIT_CALL(BPF_FUNC_sk_release),
449 BPF_EXIT_INSN(),
450
451 /* subprog 1 */
452 BPF_SK_LOOKUP(sk_lookup_tcp),
453 BPF_EXIT_INSN(), /* return sk */
454 },
455 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
456 .retval = POINTER_VALUE,
457 .result = ACCEPT,
458},
459{
460 "reference tracking in call: sk_ptr leak into caller stack",
461 .insns = {
462 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
463 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
464 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
465 BPF_MOV64_IMM(BPF_REG_0, 0),
466 BPF_EXIT_INSN(),
467
468 /* subprog 1 */
469 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
470 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
471 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
472 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
473 /* spill unchecked sk_ptr into stack of caller */
474 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
475 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
476 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
477 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
478 BPF_EXIT_INSN(),
479
480 /* subprog 2 */
481 BPF_SK_LOOKUP(sk_lookup_tcp),
482 BPF_EXIT_INSN(),
483 },
484 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
485 .errstr = "Unreleased reference",
486 .result = REJECT,
487},
488{
489 "reference tracking in call: sk_ptr spill into caller stack",
490 .insns = {
491 BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
493 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
494 BPF_MOV64_IMM(BPF_REG_0, 0),
495 BPF_EXIT_INSN(),
496
497 /* subprog 1 */
498 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
499 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
500 BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
501 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
502 /* spill unchecked sk_ptr into stack of caller */
503 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
504 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
505 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
506 BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
507 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
508 /* now the sk_ptr is verified, free the reference */
509 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_4, 0),
510 BPF_EMIT_CALL(BPF_FUNC_sk_release),
511 BPF_EXIT_INSN(),
512
513 /* subprog 2 */
514 BPF_SK_LOOKUP(sk_lookup_tcp),
515 BPF_EXIT_INSN(),
516 },
517 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
518 .result = ACCEPT,
519},
520{
521 "reference tracking: allow LD_ABS",
522 .insns = {
523 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
524 BPF_SK_LOOKUP(sk_lookup_tcp),
525 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
526 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
527 BPF_EMIT_CALL(BPF_FUNC_sk_release),
528 BPF_LD_ABS(BPF_B, 0),
529 BPF_LD_ABS(BPF_H, 0),
530 BPF_LD_ABS(BPF_W, 0),
531 BPF_EXIT_INSN(),
532 },
533 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
534 .result = ACCEPT,
535},
536{
537 "reference tracking: forbid LD_ABS while holding reference",
538 .insns = {
539 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
540 BPF_SK_LOOKUP(sk_lookup_tcp),
541 BPF_LD_ABS(BPF_B, 0),
542 BPF_LD_ABS(BPF_H, 0),
543 BPF_LD_ABS(BPF_W, 0),
544 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
545 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
546 BPF_EMIT_CALL(BPF_FUNC_sk_release),
547 BPF_EXIT_INSN(),
548 },
549 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
550 .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
551 .result = REJECT,
552},
553{
554 "reference tracking: allow LD_IND",
555 .insns = {
556 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
557 BPF_SK_LOOKUP(sk_lookup_tcp),
558 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
559 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
560 BPF_EMIT_CALL(BPF_FUNC_sk_release),
561 BPF_MOV64_IMM(BPF_REG_7, 1),
562 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
563 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
564 BPF_EXIT_INSN(),
565 },
566 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
567 .result = ACCEPT,
568 .retval = 1,
569},
570{
571 "reference tracking: forbid LD_IND while holding reference",
572 .insns = {
573 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
574 BPF_SK_LOOKUP(sk_lookup_tcp),
575 BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
576 BPF_MOV64_IMM(BPF_REG_7, 1),
577 BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
578 BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
579 BPF_MOV64_REG(BPF_REG_1, BPF_REG_4),
580 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
581 BPF_EMIT_CALL(BPF_FUNC_sk_release),
582 BPF_EXIT_INSN(),
583 },
584 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
585 .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
586 .result = REJECT,
587},
588{
589 "reference tracking: check reference or tail call",
590 .insns = {
591 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
592 BPF_SK_LOOKUP(sk_lookup_tcp),
593 /* if (sk) bpf_sk_release() */
594 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
595 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 7),
596 /* bpf_tail_call() */
597 BPF_MOV64_IMM(BPF_REG_3, 3),
598 BPF_LD_MAP_FD(BPF_REG_2, 0),
599 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
600 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
601 BPF_MOV64_IMM(BPF_REG_0, 0),
602 BPF_EXIT_INSN(),
603 BPF_EMIT_CALL(BPF_FUNC_sk_release),
604 BPF_EXIT_INSN(),
605 },
606 .fixup_prog1 = { 17 },
607 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
608 .result = ACCEPT,
609},
610{
611 "reference tracking: release reference then tail call",
612 .insns = {
613 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
614 BPF_SK_LOOKUP(sk_lookup_tcp),
615 /* if (sk) bpf_sk_release() */
616 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
617 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
618 BPF_EMIT_CALL(BPF_FUNC_sk_release),
619 /* bpf_tail_call() */
620 BPF_MOV64_IMM(BPF_REG_3, 3),
621 BPF_LD_MAP_FD(BPF_REG_2, 0),
622 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
623 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
624 BPF_MOV64_IMM(BPF_REG_0, 0),
625 BPF_EXIT_INSN(),
626 },
627 .fixup_prog1 = { 18 },
628 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
629 .result = ACCEPT,
630},
631{
632 "reference tracking: leak possible reference over tail call",
633 .insns = {
634 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
635 /* Look up socket and store in REG_6 */
636 BPF_SK_LOOKUP(sk_lookup_tcp),
637 /* bpf_tail_call() */
638 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
639 BPF_MOV64_IMM(BPF_REG_3, 3),
640 BPF_LD_MAP_FD(BPF_REG_2, 0),
641 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
642 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
643 BPF_MOV64_IMM(BPF_REG_0, 0),
644 /* if (sk) bpf_sk_release() */
645 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
646 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
647 BPF_EMIT_CALL(BPF_FUNC_sk_release),
648 BPF_EXIT_INSN(),
649 },
650 .fixup_prog1 = { 16 },
651 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
652 .errstr = "tail_call would lead to reference leak",
653 .result = REJECT,
654},
655{
656 "reference tracking: leak checked reference over tail call",
657 .insns = {
658 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
659 /* Look up socket and store in REG_6 */
660 BPF_SK_LOOKUP(sk_lookup_tcp),
661 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
662 /* if (!sk) goto end */
663 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
664 /* bpf_tail_call() */
665 BPF_MOV64_IMM(BPF_REG_3, 0),
666 BPF_LD_MAP_FD(BPF_REG_2, 0),
667 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
668 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
669 BPF_MOV64_IMM(BPF_REG_0, 0),
670 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
671 BPF_EMIT_CALL(BPF_FUNC_sk_release),
672 BPF_EXIT_INSN(),
673 },
674 .fixup_prog1 = { 17 },
675 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
676 .errstr = "tail_call would lead to reference leak",
677 .result = REJECT,
678},
679{
680 "reference tracking: mangle and release sock_or_null",
681 .insns = {
682 BPF_SK_LOOKUP(sk_lookup_tcp),
683 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
684 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
685 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
686 BPF_EMIT_CALL(BPF_FUNC_sk_release),
687 BPF_EXIT_INSN(),
688 },
689 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
690 .errstr = "R1 pointer arithmetic on sock_or_null prohibited",
691 .result = REJECT,
692},
693{
694 "reference tracking: mangle and release sock",
695 .insns = {
696 BPF_SK_LOOKUP(sk_lookup_tcp),
697 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
698 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
699 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
700 BPF_EMIT_CALL(BPF_FUNC_sk_release),
701 BPF_EXIT_INSN(),
702 },
703 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
704 .errstr = "R1 pointer arithmetic on sock prohibited",
705 .result = REJECT,
706},
707{
708 "reference tracking: access member",
709 .insns = {
710 BPF_SK_LOOKUP(sk_lookup_tcp),
711 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
712 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
713 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
714 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
715 BPF_EMIT_CALL(BPF_FUNC_sk_release),
716 BPF_EXIT_INSN(),
717 },
718 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
719 .result = ACCEPT,
720},
721{
722 "reference tracking: write to member",
723 .insns = {
724 BPF_SK_LOOKUP(sk_lookup_tcp),
725 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
726 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
727 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
728 BPF_LD_IMM64(BPF_REG_2, 42),
729 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_2,
730 offsetof(struct bpf_sock, mark)),
731 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
732 BPF_EMIT_CALL(BPF_FUNC_sk_release),
733 BPF_LD_IMM64(BPF_REG_0, 0),
734 BPF_EXIT_INSN(),
735 },
736 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
737 .errstr = "cannot write into sock",
738 .result = REJECT,
739},
740{
741 "reference tracking: invalid 64-bit access of member",
742 .insns = {
743 BPF_SK_LOOKUP(sk_lookup_tcp),
744 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
745 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
746 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
747 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
748 BPF_EMIT_CALL(BPF_FUNC_sk_release),
749 BPF_EXIT_INSN(),
750 },
751 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
752 .errstr = "invalid sock access off=0 size=8",
753 .result = REJECT,
754},
755{
756 "reference tracking: access after release",
757 .insns = {
758 BPF_SK_LOOKUP(sk_lookup_tcp),
759 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
760 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
761 BPF_EMIT_CALL(BPF_FUNC_sk_release),
762 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
763 BPF_EXIT_INSN(),
764 },
765 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
766 .errstr = "!read_ok",
767 .result = REJECT,
768},
769{
770 "reference tracking: direct access for lookup",
771 .insns = {
772 /* Check that the packet is at least 64B long */
773 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
774 offsetof(struct __sk_buff, data)),
775 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
776 offsetof(struct __sk_buff, data_end)),
777 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
778 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
779 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
780 /* sk = sk_lookup_tcp(ctx, skb->data, ...) */
781 BPF_MOV64_IMM(BPF_REG_3, sizeof(struct bpf_sock_tuple)),
782 BPF_MOV64_IMM(BPF_REG_4, 0),
783 BPF_MOV64_IMM(BPF_REG_5, 0),
784 BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
785 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
786 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
787 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
788 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
789 BPF_EMIT_CALL(BPF_FUNC_sk_release),
790 BPF_EXIT_INSN(),
791 },
792 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
793 .result = ACCEPT,
794},
795{
796 "reference tracking: use ptr from bpf_tcp_sock() after release",
797 .insns = {
798 BPF_SK_LOOKUP(sk_lookup_tcp),
799 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
800 BPF_EXIT_INSN(),
801 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
802 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
803 BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
804 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
805 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
806 BPF_EMIT_CALL(BPF_FUNC_sk_release),
807 BPF_EXIT_INSN(),
808 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
809 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
810 BPF_EMIT_CALL(BPF_FUNC_sk_release),
811 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_tcp_sock, snd_cwnd)),
812 BPF_EXIT_INSN(),
813 },
814 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
815 .result = REJECT,
816 .errstr = "invalid mem access",
817 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
818},
819{
820 "reference tracking: use ptr from bpf_sk_fullsock() after release",
821 .insns = {
822 BPF_SK_LOOKUP(sk_lookup_tcp),
823 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
824 BPF_EXIT_INSN(),
825 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
826 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
827 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
828 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
829 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
830 BPF_EMIT_CALL(BPF_FUNC_sk_release),
831 BPF_EXIT_INSN(),
832 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
833 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
834 BPF_EMIT_CALL(BPF_FUNC_sk_release),
835 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
836 BPF_EXIT_INSN(),
837 },
838 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
839 .result = REJECT,
840 .errstr = "invalid mem access",
841 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
842},
843{
844 "reference tracking: use ptr from bpf_sk_fullsock(tp) after release",
845 .insns = {
846 BPF_SK_LOOKUP(sk_lookup_tcp),
847 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
848 BPF_EXIT_INSN(),
849 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
850 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
851 BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
852 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
853 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
854 BPF_EMIT_CALL(BPF_FUNC_sk_release),
855 BPF_EXIT_INSN(),
856 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
857 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
858 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
859 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
860 BPF_EMIT_CALL(BPF_FUNC_sk_release),
861 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1),
862 BPF_EXIT_INSN(),
863 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
864 BPF_EXIT_INSN(),
865 },
866 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
867 .result = REJECT,
868 .errstr = "invalid mem access",
869 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
870},
871{
872 "reference tracking: use sk after bpf_sk_release(tp)",
873 .insns = {
874 BPF_SK_LOOKUP(sk_lookup_tcp),
875 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
876 BPF_EXIT_INSN(),
877 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
878 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
879 BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
880 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
881 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
882 BPF_EMIT_CALL(BPF_FUNC_sk_release),
883 BPF_EXIT_INSN(),
884 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
885 BPF_EMIT_CALL(BPF_FUNC_sk_release),
886 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
887 BPF_EXIT_INSN(),
888 },
889 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
890 .result = REJECT,
891 .errstr = "invalid mem access",
892 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
893},
894{
895 "reference tracking: use ptr from bpf_get_listener_sock() after bpf_sk_release(sk)",
896 .insns = {
897 BPF_SK_LOOKUP(sk_lookup_tcp),
898 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
899 BPF_EXIT_INSN(),
900 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
901 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
902 BPF_EMIT_CALL(BPF_FUNC_get_listener_sock),
903 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
904 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
905 BPF_EMIT_CALL(BPF_FUNC_sk_release),
906 BPF_EXIT_INSN(),
907 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
908 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
909 BPF_EMIT_CALL(BPF_FUNC_sk_release),
910 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, src_port)),
911 BPF_EXIT_INSN(),
912 },
913 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
914 .result = ACCEPT,
915},
916{
917 "reference tracking: bpf_sk_release(listen_sk)",
918 .insns = {
919 BPF_SK_LOOKUP(sk_lookup_tcp),
920 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
921 BPF_EXIT_INSN(),
922 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
923 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
924 BPF_EMIT_CALL(BPF_FUNC_get_listener_sock),
925 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
926 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
927 BPF_EMIT_CALL(BPF_FUNC_sk_release),
928 BPF_EXIT_INSN(),
929 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
930 BPF_EMIT_CALL(BPF_FUNC_sk_release),
931 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
932 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
933 BPF_EMIT_CALL(BPF_FUNC_sk_release),
934 BPF_EXIT_INSN(),
935 },
936 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
937 .result = REJECT,
938 .errstr = "R1 must be referenced when passed to release function",
939},
940{
941 /* !bpf_sk_fullsock(sk) is checked but !bpf_tcp_sock(sk) is not checked */
942 "reference tracking: tp->snd_cwnd after bpf_sk_fullsock(sk) and bpf_tcp_sock(sk)",
943 .insns = {
944 BPF_SK_LOOKUP(sk_lookup_tcp),
945 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
946 BPF_EXIT_INSN(),
947 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
948 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
949 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
950 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
951 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
952 BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
953 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
954 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
955 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
956 BPF_EMIT_CALL(BPF_FUNC_sk_release),
957 BPF_EXIT_INSN(),
958 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_8, offsetof(struct bpf_tcp_sock, snd_cwnd)),
959 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
960 BPF_EMIT_CALL(BPF_FUNC_sk_release),
961 BPF_EXIT_INSN(),
962 },
963 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
964 .result = REJECT,
965 .errstr = "invalid mem access",
966},
967{
968 "reference tracking: branch tracking valid pointer null comparison",
969 .insns = {
970 BPF_SK_LOOKUP(sk_lookup_tcp),
971 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
972 BPF_MOV64_IMM(BPF_REG_3, 1),
973 BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1),
974 BPF_MOV64_IMM(BPF_REG_3, 0),
975 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 2),
976 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
977 BPF_EMIT_CALL(BPF_FUNC_sk_release),
978 BPF_EXIT_INSN(),
979 },
980 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
981 .result = ACCEPT,
982},
983{
984 "reference tracking: branch tracking valid pointer value comparison",
985 .insns = {
986 BPF_SK_LOOKUP(sk_lookup_tcp),
987 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
988 BPF_MOV64_IMM(BPF_REG_3, 1),
989 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 4),
990 BPF_MOV64_IMM(BPF_REG_3, 0),
991 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 1234, 2),
992 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
993 BPF_EMIT_CALL(BPF_FUNC_sk_release),
994 BPF_EXIT_INSN(),
995 },
996 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
997 .errstr = "Unreleased reference",
998 .result = REJECT,
999},
1000{
1001 "reference tracking: bpf_sk_release(btf_tcp_sock)",
1002 .insns = {
1003 BPF_SK_LOOKUP(sk_lookup_tcp),
1004 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1005 BPF_EXIT_INSN(),
1006 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
1007 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1008 BPF_EMIT_CALL(BPF_FUNC_skc_to_tcp_sock),
1009 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
1010 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1011 BPF_EMIT_CALL(BPF_FUNC_sk_release),
1012 BPF_EXIT_INSN(),
1013 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1014 BPF_EMIT_CALL(BPF_FUNC_sk_release),
1015 BPF_EXIT_INSN(),
1016 },
1017 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1018 .result = ACCEPT,
1019 .result_unpriv = REJECT,
1020 .errstr_unpriv = "unknown func",
1021},
1022{
1023 "reference tracking: use ptr from bpf_skc_to_tcp_sock() after release",
1024 .insns = {
1025 BPF_SK_LOOKUP(sk_lookup_tcp),
1026 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1027 BPF_EXIT_INSN(),
1028 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
1029 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
1030 BPF_EMIT_CALL(BPF_FUNC_skc_to_tcp_sock),
1031 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
1032 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1033 BPF_EMIT_CALL(BPF_FUNC_sk_release),
1034 BPF_EXIT_INSN(),
1035 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
1036 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
1037 BPF_EMIT_CALL(BPF_FUNC_sk_release),
1038 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_7, 0),
1039 BPF_EXIT_INSN(),
1040 },
1041 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1042 .result = REJECT,
1043 .errstr = "invalid mem access",
1044 .result_unpriv = REJECT,
1045 .errstr_unpriv = "unknown func",
1046},
1047{
1048 "reference tracking: try to leak released ptr reg",
1049 .insns = {
1050 BPF_MOV64_IMM(BPF_REG_0, 0),
1051 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
1052 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
1053 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
1054 BPF_LD_MAP_FD(BPF_REG_1, 0),
1055 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
1056 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1057 BPF_EXIT_INSN(),
1058 BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
1059
1060 BPF_MOV64_IMM(BPF_REG_0, 0),
1061 BPF_LD_MAP_FD(BPF_REG_1, 0),
1062 BPF_MOV64_IMM(BPF_REG_2, 8),
1063 BPF_MOV64_IMM(BPF_REG_3, 0),
1064 BPF_EMIT_CALL(BPF_FUNC_ringbuf_reserve),
1065 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
1066 BPF_EXIT_INSN(),
1067 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
1068
1069 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
1070 BPF_MOV64_IMM(BPF_REG_2, 0),
1071 BPF_EMIT_CALL(BPF_FUNC_ringbuf_discard),
1072 BPF_MOV64_IMM(BPF_REG_0, 0),
1073
1074 BPF_STX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0),
1075 BPF_EXIT_INSN()
1076 },
1077 .fixup_map_array_48b = { 4 },
1078 .fixup_map_ringbuf = { 11 },
1079 .result = ACCEPT,
1080 .result_unpriv = REJECT,
1081 .errstr_unpriv = "R8 !read_ok"
1082},