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