2 "unpriv: return pointer",
4 BPF_MOV64_REG(BPF_REG_0
, BPF_REG_10
),
8 .result_unpriv
= REJECT
,
9 .errstr_unpriv
= "R0 leaks addr",
10 .retval
= POINTER_VALUE
,
13 "unpriv: add const to pointer",
15 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_1
, 8),
16 BPF_MOV64_IMM(BPF_REG_0
, 0),
22 "unpriv: add pointer to pointer",
24 BPF_ALU64_REG(BPF_ADD
, BPF_REG_1
, BPF_REG_10
),
25 BPF_MOV64_IMM(BPF_REG_0
, 0),
29 .errstr
= "R1 pointer += pointer",
32 "unpriv: neg pointer",
34 BPF_ALU64_IMM(BPF_NEG
, BPF_REG_1
, 0),
35 BPF_MOV64_IMM(BPF_REG_0
, 0),
39 .result_unpriv
= REJECT
,
40 .errstr_unpriv
= "R1 pointer arithmetic",
43 "unpriv: cmp pointer with const",
45 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 0),
46 BPF_MOV64_IMM(BPF_REG_0
, 0),
50 .result_unpriv
= REJECT
,
51 .errstr_unpriv
= "R1 pointer comparison",
54 "unpriv: cmp pointer with pointer",
56 BPF_JMP_REG(BPF_JEQ
, BPF_REG_1
, BPF_REG_10
, 0),
57 BPF_MOV64_IMM(BPF_REG_0
, 0),
61 .result_unpriv
= REJECT
,
62 .errstr_unpriv
= "R10 pointer comparison",
65 "unpriv: check that printk is disallowed",
67 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
68 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_10
),
69 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_1
, -8),
70 BPF_MOV64_IMM(BPF_REG_2
, 8),
71 BPF_MOV64_REG(BPF_REG_3
, BPF_REG_1
),
72 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_trace_printk
),
73 BPF_MOV64_IMM(BPF_REG_0
, 0),
76 .errstr_unpriv
= "unknown func bpf_trace_printk#6",
77 .result_unpriv
= REJECT
,
79 .prog_type
= BPF_PROG_TYPE_TRACEPOINT
,
82 "unpriv: pass pointer to helper function",
84 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
85 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
86 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
, -8),
87 BPF_LD_MAP_FD(BPF_REG_1
, 0),
88 BPF_MOV64_REG(BPF_REG_3
, BPF_REG_2
),
89 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_2
),
90 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_map_update_elem
),
91 BPF_MOV64_IMM(BPF_REG_0
, 0),
94 .fixup_map_hash_8b
= { 3 },
95 .errstr_unpriv
= "R4 leaks addr",
96 .result_unpriv
= REJECT
,
100 "unpriv: indirectly pass pointer on stack to helper function",
102 BPF_STX_MEM(BPF_DW
, BPF_REG_10
, BPF_REG_10
, -8),
103 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
104 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
, -8),
105 BPF_LD_MAP_FD(BPF_REG_1
, 0),
106 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_map_lookup_elem
),
107 BPF_MOV64_IMM(BPF_REG_0
, 0),
110 .fixup_map_hash_8b
= { 3 },
111 .errstr
= "invalid indirect read from stack off -8+0 size 8",
115 "unpriv: mangle pointer on stack 1",
117 BPF_STX_MEM(BPF_DW
, BPF_REG_10
, BPF_REG_10
, -8),
118 BPF_ST_MEM(BPF_W
, BPF_REG_10
, -8, 0),
119 BPF_MOV64_IMM(BPF_REG_0
, 0),
122 .errstr_unpriv
= "attempt to corrupt spilled",
123 .result_unpriv
= REJECT
,
127 "unpriv: mangle pointer on stack 2",
129 BPF_STX_MEM(BPF_DW
, BPF_REG_10
, BPF_REG_10
, -8),
130 BPF_ST_MEM(BPF_B
, BPF_REG_10
, -1, 0),
131 BPF_MOV64_IMM(BPF_REG_0
, 0),
134 .errstr_unpriv
= "attempt to corrupt spilled",
135 .result_unpriv
= REJECT
,
139 "unpriv: read pointer from stack in small chunks",
141 BPF_STX_MEM(BPF_DW
, BPF_REG_10
, BPF_REG_10
, -8),
142 BPF_LDX_MEM(BPF_W
, BPF_REG_0
, BPF_REG_10
, -8),
143 BPF_MOV64_IMM(BPF_REG_0
, 0),
146 .errstr
= "invalid size",
150 "unpriv: write pointer into ctx",
152 BPF_STX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_1
, 0),
153 BPF_MOV64_IMM(BPF_REG_0
, 0),
156 .errstr_unpriv
= "R1 leaks addr",
157 .result_unpriv
= REJECT
,
158 .errstr
= "invalid bpf_context access",
162 "unpriv: spill/fill of ctx",
164 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
165 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
166 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
167 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
168 BPF_MOV64_IMM(BPF_REG_0
, 0),
174 "unpriv: spill/fill of ctx 2",
176 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
177 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
178 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
179 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
180 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_get_hash_recalc
),
181 BPF_MOV64_IMM(BPF_REG_0
, 0),
185 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
188 "unpriv: spill/fill of ctx 3",
190 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
191 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
192 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
193 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_10
, 0),
194 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
195 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_get_hash_recalc
),
199 .errstr
= "R1 type=fp expected=ctx",
200 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
203 "unpriv: spill/fill of ctx 4",
205 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
206 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
207 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
208 BPF_MOV64_IMM(BPF_REG_0
, 1),
209 BPF_RAW_INSN(BPF_STX
| BPF_XADD
| BPF_DW
, BPF_REG_10
, BPF_REG_0
, -8, 0),
210 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
211 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_get_hash_recalc
),
215 .errstr
= "R1 type=inv expected=ctx",
216 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
219 "unpriv: spill/fill of different pointers stx",
221 BPF_MOV64_IMM(BPF_REG_3
, 42),
222 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
223 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
224 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 3),
225 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
226 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
, -16),
227 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
228 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
229 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
230 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
231 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_3
,
232 offsetof(struct __sk_buff
, mark
)),
233 BPF_MOV64_IMM(BPF_REG_0
, 0),
237 .errstr
= "same insn cannot be used with different pointers",
238 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
241 "unpriv: spill/fill of different pointers stx - ctx and sock",
243 BPF_MOV64_REG(BPF_REG_8
, BPF_REG_1
),
244 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
245 BPF_SK_LOOKUP(sk_lookup_tcp
),
246 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_0
),
248 /* void *target = &foo; */
249 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
250 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
251 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_8
),
252 /* if (skb == NULL) *target = sock; */
253 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 1),
254 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
255 /* else *target = skb; */
256 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
257 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
258 /* struct __sk_buff *skb = *target; */
259 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
260 /* skb->mark = 42; */
261 BPF_MOV64_IMM(BPF_REG_3
, 42),
262 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_3
,
263 offsetof(struct __sk_buff
, mark
)),
264 /* if (sk) bpf_sk_release(sk) */
265 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 1),
266 BPF_EMIT_CALL(BPF_FUNC_sk_release
),
267 BPF_MOV64_IMM(BPF_REG_0
, 0),
271 .errstr
= "type=ctx expected=sock",
272 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
275 "unpriv: spill/fill of different pointers stx - leak sock",
277 BPF_MOV64_REG(BPF_REG_8
, BPF_REG_1
),
278 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
279 BPF_SK_LOOKUP(sk_lookup_tcp
),
280 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_0
),
282 /* void *target = &foo; */
283 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
284 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
285 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_8
),
286 /* if (skb == NULL) *target = sock; */
287 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 1),
288 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
289 /* else *target = skb; */
290 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
291 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
292 /* struct __sk_buff *skb = *target; */
293 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
294 /* skb->mark = 42; */
295 BPF_MOV64_IMM(BPF_REG_3
, 42),
296 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_3
,
297 offsetof(struct __sk_buff
, mark
)),
301 //.errstr = "same insn cannot be used with different pointers",
302 .errstr
= "Unreleased reference",
303 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
306 "unpriv: spill/fill of different pointers stx - sock and ctx (read)",
308 BPF_MOV64_REG(BPF_REG_8
, BPF_REG_1
),
309 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
310 BPF_SK_LOOKUP(sk_lookup_tcp
),
311 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_0
),
313 /* void *target = &foo; */
314 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
315 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
316 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_8
),
317 /* if (skb) *target = skb */
318 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 1),
319 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
320 /* else *target = sock */
321 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
322 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
323 /* struct bpf_sock *sk = *target; */
324 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
325 /* if (sk) u32 foo = sk->mark; bpf_sk_release(sk); */
326 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 2),
327 BPF_LDX_MEM(BPF_W
, BPF_REG_3
, BPF_REG_1
,
328 offsetof(struct bpf_sock
, mark
)),
329 BPF_EMIT_CALL(BPF_FUNC_sk_release
),
330 BPF_MOV64_IMM(BPF_REG_0
, 0),
334 .errstr
= "same insn cannot be used with different pointers",
335 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
338 "unpriv: spill/fill of different pointers stx - sock and ctx (write)",
340 BPF_MOV64_REG(BPF_REG_8
, BPF_REG_1
),
341 /* struct bpf_sock *sock = bpf_sock_lookup(...); */
342 BPF_SK_LOOKUP(sk_lookup_tcp
),
343 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_0
),
345 /* void *target = &foo; */
346 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
347 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
348 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_8
),
349 /* if (skb) *target = skb */
350 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 1),
351 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
352 /* else *target = sock */
353 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
354 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
355 /* struct bpf_sock *sk = *target; */
356 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
357 /* if (sk) sk->mark = 42; bpf_sk_release(sk); */
358 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 3),
359 BPF_MOV64_IMM(BPF_REG_3
, 42),
360 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_3
,
361 offsetof(struct bpf_sock
, mark
)),
362 BPF_EMIT_CALL(BPF_FUNC_sk_release
),
363 BPF_MOV64_IMM(BPF_REG_0
, 0),
367 //.errstr = "same insn cannot be used with different pointers",
368 .errstr
= "cannot write into sock",
369 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
372 "unpriv: spill/fill of different pointers ldx",
374 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
375 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
376 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 3),
377 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
378 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
,
379 -(__s32
)offsetof(struct bpf_perf_event_data
,
381 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_2
, 0),
382 BPF_JMP_IMM(BPF_JNE
, BPF_REG_1
, 0, 1),
383 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_1
, 0),
384 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_6
, 0),
385 BPF_LDX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_1
,
386 offsetof(struct bpf_perf_event_data
, sample_period
)),
387 BPF_MOV64_IMM(BPF_REG_0
, 0),
391 .errstr
= "same insn cannot be used with different pointers",
392 .prog_type
= BPF_PROG_TYPE_PERF_EVENT
,
395 "unpriv: write pointer into map elem value",
397 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
398 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
399 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
, -8),
400 BPF_LD_MAP_FD(BPF_REG_1
, 0),
401 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_map_lookup_elem
),
402 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_0
, 0, 1),
403 BPF_STX_MEM(BPF_DW
, BPF_REG_0
, BPF_REG_0
, 0),
406 .fixup_map_hash_8b
= { 3 },
407 .errstr_unpriv
= "R0 leaks addr",
408 .result_unpriv
= REJECT
,
412 "alu32: mov u32 const",
414 BPF_MOV32_IMM(BPF_REG_7
, 0),
415 BPF_ALU32_IMM(BPF_AND
, BPF_REG_7
, 1),
416 BPF_MOV32_REG(BPF_REG_0
, BPF_REG_7
),
417 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_0
, 0, 1),
418 BPF_LDX_MEM(BPF_DW
, BPF_REG_0
, BPF_REG_7
, 0),
425 "unpriv: partial copy of pointer",
427 BPF_MOV32_REG(BPF_REG_1
, BPF_REG_10
),
428 BPF_MOV64_IMM(BPF_REG_0
, 0),
431 .errstr_unpriv
= "R10 partial copy",
432 .result_unpriv
= REJECT
,
436 "unpriv: pass pointer to tail_call",
438 BPF_MOV64_REG(BPF_REG_3
, BPF_REG_1
),
439 BPF_LD_MAP_FD(BPF_REG_2
, 0),
440 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_tail_call
),
441 BPF_MOV64_IMM(BPF_REG_0
, 0),
444 .fixup_prog1
= { 1 },
445 .errstr_unpriv
= "R3 leaks addr into helper",
446 .result_unpriv
= REJECT
,
450 "unpriv: cmp map pointer with zero",
452 BPF_MOV64_IMM(BPF_REG_1
, 0),
453 BPF_LD_MAP_FD(BPF_REG_1
, 0),
454 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_1
, 0, 0),
455 BPF_MOV64_IMM(BPF_REG_0
, 0),
458 .fixup_map_hash_8b
= { 1 },
459 .errstr_unpriv
= "R1 pointer comparison",
460 .result_unpriv
= REJECT
,
464 "unpriv: write into frame pointer",
466 BPF_MOV64_REG(BPF_REG_10
, BPF_REG_1
),
467 BPF_MOV64_IMM(BPF_REG_0
, 0),
470 .errstr
= "frame pointer is read only",
474 "unpriv: spill/fill frame pointer",
476 BPF_ALU64_REG(BPF_MOV
, BPF_REG_6
, BPF_REG_10
),
477 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_6
, -8),
478 BPF_STX_MEM(BPF_DW
, BPF_REG_6
, BPF_REG_10
, 0),
479 BPF_LDX_MEM(BPF_DW
, BPF_REG_10
, BPF_REG_6
, 0),
480 BPF_MOV64_IMM(BPF_REG_0
, 0),
483 .errstr
= "frame pointer is read only",
487 "unpriv: cmp of frame pointer",
489 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_10
, 0, 0),
490 BPF_MOV64_IMM(BPF_REG_0
, 0),
493 .errstr_unpriv
= "R10 pointer comparison",
494 .result_unpriv
= REJECT
,
498 "unpriv: adding of fp",
500 BPF_MOV64_IMM(BPF_REG_0
, 0),
501 BPF_MOV64_IMM(BPF_REG_1
, 0),
502 BPF_ALU64_REG(BPF_ADD
, BPF_REG_1
, BPF_REG_10
),
503 BPF_STX_MEM(BPF_DW
, BPF_REG_1
, BPF_REG_0
, -8),
506 .errstr_unpriv
= "R1 stack pointer arithmetic goes out of range",
507 .result_unpriv
= REJECT
,
511 "unpriv: cmp of stack pointer",
513 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_10
),
514 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_2
, -8),
515 BPF_JMP_IMM(BPF_JEQ
, BPF_REG_2
, 0, 0),
516 BPF_MOV64_IMM(BPF_REG_0
, 0),
519 .errstr_unpriv
= "R2 pointer comparison",
520 .result_unpriv
= REJECT
,