1 {
2 	"map access: known scalar += value_ptr from different maps",
3 	.insns = {
4 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
5 		    offsetof(struct __sk_buff, len)),
6 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
7 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
8 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
9 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3),
10 	BPF_LD_MAP_FD(BPF_REG_1, 0),
11 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
12 	BPF_LD_MAP_FD(BPF_REG_1, 0),
13 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
14 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
15 	BPF_MOV64_IMM(BPF_REG_1, 4),
16 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
17 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
18 	BPF_MOV64_IMM(BPF_REG_0, 1),
19 	BPF_EXIT_INSN(),
20 	},
21 	.fixup_map_hash_16b = { 5 },
22 	.fixup_map_array_48b = { 8 },
23 	.result = ACCEPT,
24 	.retval = 1,
25 },
26 {
27 	"map access: value_ptr -= known scalar from different maps",
28 	.insns = {
29 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
30 		    offsetof(struct __sk_buff, len)),
31 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
32 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
33 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
34 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3),
35 	BPF_LD_MAP_FD(BPF_REG_1, 0),
36 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
37 	BPF_LD_MAP_FD(BPF_REG_1, 0),
38 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
39 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
40 	BPF_MOV64_IMM(BPF_REG_1, 4),
41 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
42 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
43 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
44 	BPF_MOV64_IMM(BPF_REG_0, 1),
45 	BPF_EXIT_INSN(),
46 	},
47 	.fixup_map_hash_16b = { 5 },
48 	.fixup_map_array_48b = { 8 },
49 	.result = ACCEPT,
50 	.result_unpriv = REJECT,
51 	.errstr_unpriv = "R0 min value is outside of the allowed memory range",
52 	.retval = 1,
53 },
54 {
55 	"map access: known scalar += value_ptr from different maps, but same value properties",
56 	.insns = {
57 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
58 		    offsetof(struct __sk_buff, len)),
59 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
60 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
61 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
62 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3),
63 	BPF_LD_MAP_FD(BPF_REG_1, 0),
64 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2),
65 	BPF_LD_MAP_FD(BPF_REG_1, 0),
66 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
67 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
68 	BPF_MOV64_IMM(BPF_REG_1, 4),
69 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
70 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
71 	BPF_MOV64_IMM(BPF_REG_0, 1),
72 	BPF_EXIT_INSN(),
73 	},
74 	.fixup_map_hash_48b = { 5 },
75 	.fixup_map_array_48b = { 8 },
76 	.result = ACCEPT,
77 	.retval = 1,
78 },
79 {
80 	"map access: mixing value pointer and scalar, 1",
81 	.insns = {
82 	// load map value pointer into r0 and r2
83 	BPF_MOV64_IMM(BPF_REG_0, 1),
84 	BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
85 	BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
86 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16),
87 	BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0),
88 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
89 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
90 	BPF_EXIT_INSN(),
91 	// load some number from the map into r1
92 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
93 	// depending on r1, branch:
94 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 3),
95 	// branch A
96 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
97 	BPF_MOV64_IMM(BPF_REG_3, 0),
98 	BPF_JMP_A(2),
99 	// branch B
100 	BPF_MOV64_IMM(BPF_REG_2, 0),
101 	BPF_MOV64_IMM(BPF_REG_3, 0x100000),
102 	// common instruction
103 	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
104 	// depending on r1, branch:
105 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
106 	// branch A
107 	BPF_JMP_A(4),
108 	// branch B
109 	BPF_MOV64_IMM(BPF_REG_0, 0x13371337),
110 	// verifier follows fall-through
111 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2),
112 	BPF_MOV64_IMM(BPF_REG_0, 0),
113 	BPF_EXIT_INSN(),
114 	// fake-dead code; targeted from branch A to
115 	// prevent dead code sanitization
116 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
117 	BPF_MOV64_IMM(BPF_REG_0, 0),
118 	BPF_EXIT_INSN(),
119 	},
120 	.fixup_map_array_48b = { 1 },
121 	.result = ACCEPT,
122 	.result_unpriv = REJECT,
123 	.errstr_unpriv = "R2 pointer comparison prohibited",
124 	.retval = 0,
125 },
126 {
127 	"map access: mixing value pointer and scalar, 2",
128 	.insns = {
129 	// load map value pointer into r0 and r2
130 	BPF_MOV64_IMM(BPF_REG_0, 1),
131 	BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
132 	BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
133 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16),
134 	BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0),
135 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
136 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
137 	BPF_EXIT_INSN(),
138 	// load some number from the map into r1
139 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
140 	// depending on r1, branch:
141 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
142 	// branch A
143 	BPF_MOV64_IMM(BPF_REG_2, 0),
144 	BPF_MOV64_IMM(BPF_REG_3, 0x100000),
145 	BPF_JMP_A(2),
146 	// branch B
147 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
148 	BPF_MOV64_IMM(BPF_REG_3, 0),
149 	// common instruction
150 	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
151 	// depending on r1, branch:
152 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
153 	// branch A
154 	BPF_JMP_A(4),
155 	// branch B
156 	BPF_MOV64_IMM(BPF_REG_0, 0x13371337),
157 	// verifier follows fall-through
158 	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2),
159 	BPF_MOV64_IMM(BPF_REG_0, 0),
160 	BPF_EXIT_INSN(),
161 	// fake-dead code; targeted from branch A to
162 	// prevent dead code sanitization, rejected
163 	// via branch B however
164 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
165 	BPF_MOV64_IMM(BPF_REG_0, 0),
166 	BPF_EXIT_INSN(),
167 	},
168 	.fixup_map_array_48b = { 1 },
169 	.result = ACCEPT,
170 	.result_unpriv = REJECT,
171 	.errstr_unpriv = "R0 invalid mem access 'inv'",
172 	.retval = 0,
173 },
174 {
175 	"sanitation: alu with different scalars 1",
176 	.insns = {
177 	BPF_MOV64_IMM(BPF_REG_0, 1),
178 	BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
179 	BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
180 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16),
181 	BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0),
182 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
183 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
184 	BPF_EXIT_INSN(),
185 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
186 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3),
187 	BPF_MOV64_IMM(BPF_REG_2, 0),
188 	BPF_MOV64_IMM(BPF_REG_3, 0x100000),
189 	BPF_JMP_A(2),
190 	BPF_MOV64_IMM(BPF_REG_2, 42),
191 	BPF_MOV64_IMM(BPF_REG_3, 0x100001),
192 	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3),
193 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
194 	BPF_EXIT_INSN(),
195 	},
196 	.fixup_map_array_48b = { 1 },
197 	.result = ACCEPT,
198 	.retval = 0x100000,
199 },
200 {
201 	"sanitation: alu with different scalars 2",
202 	.insns = {
203 	BPF_MOV64_IMM(BPF_REG_0, 1),
204 	BPF_LD_MAP_FD(BPF_REG_1, 0),
205 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
206 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
207 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
208 	BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0),
209 	BPF_EMIT_CALL(BPF_FUNC_map_delete_elem),
210 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
211 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
212 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
213 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
214 	BPF_EMIT_CALL(BPF_FUNC_map_delete_elem),
215 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
216 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
217 	BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_7),
218 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
219 	BPF_EXIT_INSN(),
220 	},
221 	.fixup_map_array_48b = { 1 },
222 	.result = ACCEPT,
223 	.retval = -EINVAL * 2,
224 },
225 {
226 	"sanitation: alu with different scalars 3",
227 	.insns = {
228 	BPF_MOV64_IMM(BPF_REG_0, EINVAL),
229 	BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, -1),
230 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
231 	BPF_MOV64_IMM(BPF_REG_0, EINVAL),
232 	BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, -1),
233 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
234 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_6),
235 	BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_7),
236 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_8),
237 	BPF_EXIT_INSN(),
238 	},
239 	.result = ACCEPT,
240 	.retval = -EINVAL * 2,
241 },
242 {
243 	"map access: value_ptr += known scalar, upper oob arith, test 1",
244 	.insns = {
245 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
246 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
247 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
248 	BPF_LD_MAP_FD(BPF_REG_1, 0),
249 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
250 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
251 	BPF_MOV64_IMM(BPF_REG_1, 48),
252 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
253 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
254 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
255 	BPF_MOV64_IMM(BPF_REG_0, 1),
256 	BPF_EXIT_INSN(),
257 	},
258 	.fixup_map_array_48b = { 3 },
259 	.result = ACCEPT,
260 	.result_unpriv = REJECT,
261 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
262 	.retval = 1,
263 },
264 {
265 	"map access: value_ptr += known scalar, upper oob arith, test 2",
266 	.insns = {
267 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
268 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
269 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
270 	BPF_LD_MAP_FD(BPF_REG_1, 0),
271 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
272 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
273 	BPF_MOV64_IMM(BPF_REG_1, 49),
274 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
275 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
276 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
277 	BPF_MOV64_IMM(BPF_REG_0, 1),
278 	BPF_EXIT_INSN(),
279 	},
280 	.fixup_map_array_48b = { 3 },
281 	.result = ACCEPT,
282 	.result_unpriv = REJECT,
283 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
284 	.retval = 1,
285 },
286 {
287 	"map access: value_ptr += known scalar, upper oob arith, test 3",
288 	.insns = {
289 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
290 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
291 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
292 	BPF_LD_MAP_FD(BPF_REG_1, 0),
293 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
294 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
295 	BPF_MOV64_IMM(BPF_REG_1, 47),
296 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
297 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
298 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
299 	BPF_MOV64_IMM(BPF_REG_0, 1),
300 	BPF_EXIT_INSN(),
301 	},
302 	.fixup_map_array_48b = { 3 },
303 	.result = ACCEPT,
304 	.retval = 1,
305 },
306 {
307 	"map access: value_ptr -= known scalar, lower oob arith, test 1",
308 	.insns = {
309 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
310 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
311 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
312 	BPF_LD_MAP_FD(BPF_REG_1, 0),
313 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
314 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
315 	BPF_MOV64_IMM(BPF_REG_1, 47),
316 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
317 	BPF_MOV64_IMM(BPF_REG_1, 48),
318 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
319 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
320 	BPF_MOV64_IMM(BPF_REG_0, 1),
321 	BPF_EXIT_INSN(),
322 	},
323 	.fixup_map_array_48b = { 3 },
324 	.result = REJECT,
325 	.errstr = "R0 min value is outside of the allowed memory range",
326 	.result_unpriv = REJECT,
327 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
328 },
329 {
330 	"map access: value_ptr -= known scalar, lower oob arith, test 2",
331 	.insns = {
332 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
333 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
334 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
335 	BPF_LD_MAP_FD(BPF_REG_1, 0),
336 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
337 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
338 	BPF_MOV64_IMM(BPF_REG_1, 47),
339 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
340 	BPF_MOV64_IMM(BPF_REG_1, 48),
341 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
342 	BPF_MOV64_IMM(BPF_REG_1, 1),
343 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
344 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
345 	BPF_MOV64_IMM(BPF_REG_0, 1),
346 	BPF_EXIT_INSN(),
347 	},
348 	.fixup_map_array_48b = { 3 },
349 	.result = ACCEPT,
350 	.result_unpriv = REJECT,
351 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
352 	.retval = 1,
353 },
354 {
355 	"map access: value_ptr -= known scalar, lower oob arith, test 3",
356 	.insns = {
357 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
358 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
359 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
360 	BPF_LD_MAP_FD(BPF_REG_1, 0),
361 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
362 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
363 	BPF_MOV64_IMM(BPF_REG_1, 47),
364 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
365 	BPF_MOV64_IMM(BPF_REG_1, 47),
366 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
367 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
368 	BPF_MOV64_IMM(BPF_REG_0, 1),
369 	BPF_EXIT_INSN(),
370 	},
371 	.fixup_map_array_48b = { 3 },
372 	.result = ACCEPT,
373 	.retval = 1,
374 },
375 {
376 	"map access: known scalar += value_ptr",
377 	.insns = {
378 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
379 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
380 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
381 	BPF_LD_MAP_FD(BPF_REG_1, 0),
382 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
383 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
384 	BPF_MOV64_IMM(BPF_REG_1, 4),
385 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
386 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
387 	BPF_MOV64_IMM(BPF_REG_0, 1),
388 	BPF_EXIT_INSN(),
389 	},
390 	.fixup_map_array_48b = { 3 },
391 	.result = ACCEPT,
392 	.retval = 1,
393 },
394 {
395 	"map access: value_ptr += known scalar, 1",
396 	.insns = {
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, 3),
403 	BPF_MOV64_IMM(BPF_REG_1, 4),
404 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
405 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
406 	BPF_MOV64_IMM(BPF_REG_0, 1),
407 	BPF_EXIT_INSN(),
408 	},
409 	.fixup_map_array_48b = { 3 },
410 	.result = ACCEPT,
411 	.retval = 1,
412 },
413 {
414 	"map access: value_ptr += known scalar, 2",
415 	.insns = {
416 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
417 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
418 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
419 	BPF_LD_MAP_FD(BPF_REG_1, 0),
420 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
421 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
422 	BPF_MOV64_IMM(BPF_REG_1, 49),
423 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
424 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
425 	BPF_MOV64_IMM(BPF_REG_0, 1),
426 	BPF_EXIT_INSN(),
427 	},
428 	.fixup_map_array_48b = { 3 },
429 	.result = REJECT,
430 	.errstr = "invalid access to map value",
431 },
432 {
433 	"map access: value_ptr += known scalar, 3",
434 	.insns = {
435 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
436 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
437 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
438 	BPF_LD_MAP_FD(BPF_REG_1, 0),
439 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
440 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
441 	BPF_MOV64_IMM(BPF_REG_1, -1),
442 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
443 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
444 	BPF_MOV64_IMM(BPF_REG_0, 1),
445 	BPF_EXIT_INSN(),
446 	},
447 	.fixup_map_array_48b = { 3 },
448 	.result = REJECT,
449 	.errstr = "invalid access to map value",
450 },
451 {
452 	"map access: value_ptr += known scalar, 4",
453 	.insns = {
454 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
455 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
456 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
457 	BPF_LD_MAP_FD(BPF_REG_1, 0),
458 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
459 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
460 	BPF_MOV64_IMM(BPF_REG_1, 5),
461 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
462 	BPF_MOV64_IMM(BPF_REG_1, -2),
463 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
464 	BPF_MOV64_IMM(BPF_REG_1, -1),
465 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
466 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
467 	BPF_MOV64_IMM(BPF_REG_0, 1),
468 	BPF_EXIT_INSN(),
469 	},
470 	.fixup_map_array_48b = { 3 },
471 	.result = ACCEPT,
472 	.retval = 1,
473 },
474 {
475 	"map access: value_ptr += known scalar, 5",
476 	.insns = {
477 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
478 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
479 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
480 	BPF_LD_MAP_FD(BPF_REG_1, 0),
481 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
482 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
483 	BPF_MOV64_IMM(BPF_REG_1, (6 + 1) * sizeof(int)),
484 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
485 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
486 	BPF_EXIT_INSN(),
487 	},
488 	.fixup_map_array_48b = { 3 },
489 	.result = ACCEPT,
490 	.retval = 0xabcdef12,
491 },
492 {
493 	"map access: value_ptr += known scalar, 6",
494 	.insns = {
495 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
496 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
497 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
498 	BPF_LD_MAP_FD(BPF_REG_1, 0),
499 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
500 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
501 	BPF_MOV64_IMM(BPF_REG_1, (3 + 1) * sizeof(int)),
502 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
503 	BPF_MOV64_IMM(BPF_REG_1, 3 * sizeof(int)),
504 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
505 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
506 	BPF_EXIT_INSN(),
507 	},
508 	.fixup_map_array_48b = { 3 },
509 	.result = ACCEPT,
510 	.retval = 0xabcdef12,
511 },
512 {
513 	"map access: value_ptr += N, value_ptr -= N known scalar",
514 	.insns = {
515 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
516 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
517 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
518 	BPF_LD_MAP_FD(BPF_REG_1, 0),
519 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
520 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
521 	BPF_MOV32_IMM(BPF_REG_1, 0x12345678),
522 	BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
523 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2),
524 	BPF_MOV64_IMM(BPF_REG_1, 2),
525 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
526 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
527 	BPF_EXIT_INSN(),
528 	},
529 	.fixup_map_array_48b = { 3 },
530 	.result = ACCEPT,
531 	.retval = 0x12345678,
532 },
533 {
534 	"map access: unknown scalar += value_ptr, 1",
535 	.insns = {
536 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
537 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
538 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
539 	BPF_LD_MAP_FD(BPF_REG_1, 0),
540 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
541 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
542 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
543 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
544 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
545 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
546 	BPF_MOV64_IMM(BPF_REG_0, 1),
547 	BPF_EXIT_INSN(),
548 	},
549 	.fixup_map_array_48b = { 3 },
550 	.result = ACCEPT,
551 	.retval = 1,
552 },
553 {
554 	"map access: unknown scalar += value_ptr, 2",
555 	.insns = {
556 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
557 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
558 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
559 	BPF_LD_MAP_FD(BPF_REG_1, 0),
560 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
561 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
562 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
563 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31),
564 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
565 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
566 	BPF_EXIT_INSN(),
567 	},
568 	.fixup_map_array_48b = { 3 },
569 	.result = ACCEPT,
570 	.retval = 0xabcdef12,
571 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
572 },
573 {
574 	"map access: unknown scalar += value_ptr, 3",
575 	.insns = {
576 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
577 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
578 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
579 	BPF_LD_MAP_FD(BPF_REG_1, 0),
580 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
581 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
582 	BPF_MOV64_IMM(BPF_REG_1, -1),
583 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
584 	BPF_MOV64_IMM(BPF_REG_1, 1),
585 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
586 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
587 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31),
588 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
589 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
590 	BPF_EXIT_INSN(),
591 	},
592 	.fixup_map_array_48b = { 3 },
593 	.result = ACCEPT,
594 	.result_unpriv = REJECT,
595 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
596 	.retval = 0xabcdef12,
597 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
598 },
599 {
600 	"map access: unknown scalar += value_ptr, 4",
601 	.insns = {
602 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
603 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
604 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
605 	BPF_LD_MAP_FD(BPF_REG_1, 0),
606 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
607 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
608 	BPF_MOV64_IMM(BPF_REG_1, 19),
609 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
610 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
611 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31),
612 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0),
613 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
614 	BPF_EXIT_INSN(),
615 	},
616 	.fixup_map_array_48b = { 3 },
617 	.result = REJECT,
618 	.errstr = "R1 max value is outside of the allowed memory range",
619 	.errstr_unpriv = "R1 pointer arithmetic of map value goes out of range",
620 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
621 },
622 {
623 	"map access: value_ptr += unknown scalar, 1",
624 	.insns = {
625 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
626 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
627 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
628 	BPF_LD_MAP_FD(BPF_REG_1, 0),
629 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
630 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
631 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
632 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
633 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
634 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
635 	BPF_MOV64_IMM(BPF_REG_0, 1),
636 	BPF_EXIT_INSN(),
637 	},
638 	.fixup_map_array_48b = { 3 },
639 	.result = ACCEPT,
640 	.retval = 1,
641 },
642 {
643 	"map access: value_ptr += unknown scalar, 2",
644 	.insns = {
645 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
646 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
647 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
648 	BPF_LD_MAP_FD(BPF_REG_1, 0),
649 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
650 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
651 	BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
652 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31),
653 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
654 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
655 	BPF_EXIT_INSN(),
656 	},
657 	.fixup_map_array_48b = { 3 },
658 	.result = ACCEPT,
659 	.retval = 0xabcdef12,
660 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
661 },
662 {
663 	"map access: value_ptr += unknown scalar, 3",
664 	.insns = {
665 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
666 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
667 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
668 	BPF_LD_MAP_FD(BPF_REG_1, 0),
669 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
670 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
671 	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
672 	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 8),
673 	BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 16),
674 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
675 	BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 1),
676 	BPF_ALU64_IMM(BPF_OR, BPF_REG_3, 1),
677 	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_3, 4),
678 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
679 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
680 	BPF_MOV64_IMM(BPF_REG_0, 1),
681 	BPF_EXIT_INSN(),
682 	BPF_MOV64_IMM(BPF_REG_0, 2),
683 	BPF_JMP_IMM(BPF_JA, 0, 0, -3),
684 	},
685 	.fixup_map_array_48b = { 3 },
686 	.result = ACCEPT,
687 	.retval = 1,
688 },
689 {
690 	"map access: value_ptr += value_ptr",
691 	.insns = {
692 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
693 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
694 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
695 	BPF_LD_MAP_FD(BPF_REG_1, 0),
696 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
697 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
698 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_0),
699 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
700 	BPF_MOV64_IMM(BPF_REG_0, 1),
701 	BPF_EXIT_INSN(),
702 	},
703 	.fixup_map_array_48b = { 3 },
704 	.result = REJECT,
705 	.errstr = "R0 pointer += pointer prohibited",
706 },
707 {
708 	"map access: known scalar -= value_ptr",
709 	.insns = {
710 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
711 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
712 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
713 	BPF_LD_MAP_FD(BPF_REG_1, 0),
714 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
715 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
716 	BPF_MOV64_IMM(BPF_REG_1, 4),
717 	BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
718 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
719 	BPF_MOV64_IMM(BPF_REG_0, 1),
720 	BPF_EXIT_INSN(),
721 	},
722 	.fixup_map_array_48b = { 3 },
723 	.result = REJECT,
724 	.errstr = "R1 tried to subtract pointer from scalar",
725 },
726 {
727 	"map access: value_ptr -= known scalar",
728 	.insns = {
729 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
730 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
731 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
732 	BPF_LD_MAP_FD(BPF_REG_1, 0),
733 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
734 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
735 	BPF_MOV64_IMM(BPF_REG_1, 4),
736 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
737 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
738 	BPF_MOV64_IMM(BPF_REG_0, 1),
739 	BPF_EXIT_INSN(),
740 	},
741 	.fixup_map_array_48b = { 3 },
742 	.result = REJECT,
743 	.errstr = "R0 min value is outside of the allowed memory range",
744 },
745 {
746 	"map access: value_ptr -= known scalar, 2",
747 	.insns = {
748 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
749 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
750 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
751 	BPF_LD_MAP_FD(BPF_REG_1, 0),
752 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
753 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
754 	BPF_MOV64_IMM(BPF_REG_1, 6),
755 	BPF_MOV64_IMM(BPF_REG_2, 4),
756 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
757 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2),
758 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
759 	BPF_MOV64_IMM(BPF_REG_0, 1),
760 	BPF_EXIT_INSN(),
761 	},
762 	.fixup_map_array_48b = { 3 },
763 	.result = ACCEPT,
764 	.retval = 1,
765 },
766 {
767 	"map access: unknown scalar -= value_ptr",
768 	.insns = {
769 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
770 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
771 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
772 	BPF_LD_MAP_FD(BPF_REG_1, 0),
773 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
774 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
775 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
776 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
777 	BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
778 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
779 	BPF_MOV64_IMM(BPF_REG_0, 1),
780 	BPF_EXIT_INSN(),
781 	},
782 	.fixup_map_array_48b = { 3 },
783 	.result = REJECT,
784 	.errstr = "R1 tried to subtract pointer from scalar",
785 },
786 {
787 	"map access: value_ptr -= unknown scalar",
788 	.insns = {
789 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
790 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
791 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
792 	BPF_LD_MAP_FD(BPF_REG_1, 0),
793 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
794 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
795 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
796 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
797 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
798 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
799 	BPF_MOV64_IMM(BPF_REG_0, 1),
800 	BPF_EXIT_INSN(),
801 	},
802 	.fixup_map_array_48b = { 3 },
803 	.result = REJECT,
804 	.errstr = "R0 min value is negative",
805 },
806 {
807 	"map access: value_ptr -= unknown scalar, 2",
808 	.insns = {
809 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
810 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
811 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
812 	BPF_LD_MAP_FD(BPF_REG_1, 0),
813 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
814 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
815 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
816 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf),
817 	BPF_ALU64_IMM(BPF_OR, BPF_REG_1, 0x7),
818 	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
819 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
820 	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7),
821 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
822 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
823 	BPF_MOV64_IMM(BPF_REG_0, 1),
824 	BPF_EXIT_INSN(),
825 	},
826 	.fixup_map_array_48b = { 3 },
827 	.result = ACCEPT,
828 	.result_unpriv = REJECT,
829 	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
830 	.retval = 1,
831 },
832 {
833 	"map access: value_ptr -= value_ptr",
834 	.insns = {
835 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
836 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
837 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
838 	BPF_LD_MAP_FD(BPF_REG_1, 0),
839 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
840 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
841 	BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_0),
842 	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
843 	BPF_MOV64_IMM(BPF_REG_0, 1),
844 	BPF_EXIT_INSN(),
845 	},
846 	.fixup_map_array_48b = { 3 },
847 	.result = REJECT,
848 	.errstr = "R0 invalid mem access 'inv'",
849 	.errstr_unpriv = "R0 pointer -= pointer prohibited",
850 },
851 {
852 	"map access: trying to leak tained dst reg",
853 	.insns = {
854 	BPF_MOV64_IMM(BPF_REG_0, 0),
855 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
856 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
857 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
858 	BPF_LD_MAP_FD(BPF_REG_1, 0),
859 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
860 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
861 	BPF_EXIT_INSN(),
862 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),
863 	BPF_MOV32_IMM(BPF_REG_1, 0xFFFFFFFF),
864 	BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
865 	BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_1),
866 	BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0),
867 	BPF_MOV64_IMM(BPF_REG_0, 0),
868 	BPF_EXIT_INSN(),
869 	},
870 	.fixup_map_array_48b = { 4 },
871 	.result = REJECT,
872 	.errstr = "math between map_value pointer and 4294967295 is not allowed",
873 },
874 {
875 	"32bit pkt_ptr -= scalar",
876 	.insns = {
877 	BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
878 		    offsetof(struct __sk_buff, data_end)),
879 	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
880 		    offsetof(struct __sk_buff, data)),
881 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
882 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 40),
883 	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_8, 2),
884 	BPF_ALU32_REG(BPF_MOV, BPF_REG_4, BPF_REG_7),
885 	BPF_ALU32_REG(BPF_SUB, BPF_REG_6, BPF_REG_4),
886 	BPF_MOV64_IMM(BPF_REG_0, 0),
887 	BPF_EXIT_INSN(),
888 	},
889 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
890 	.result = ACCEPT,
891 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
892 },
893 {
894 	"32bit scalar -= pkt_ptr",
895 	.insns = {
896 	BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
897 		    offsetof(struct __sk_buff, data_end)),
898 	BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
899 		    offsetof(struct __sk_buff, data)),
900 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
901 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 40),
902 	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_8, 2),
903 	BPF_ALU32_REG(BPF_MOV, BPF_REG_4, BPF_REG_6),
904 	BPF_ALU32_REG(BPF_SUB, BPF_REG_4, BPF_REG_7),
905 	BPF_MOV64_IMM(BPF_REG_0, 0),
906 	BPF_EXIT_INSN(),
907 	},
908 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
909 	.result = ACCEPT,
910 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
911 },
912