1 {
2 	"PTR_TO_STACK store/load",
3 	.insns = {
4 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
6 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
7 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
8 	BPF_EXIT_INSN(),
9 	},
10 	.result = ACCEPT,
11 	.retval = 0xfaceb00c,
12 },
13 {
14 	"PTR_TO_STACK store/load - bad alignment on off",
15 	.insns = {
16 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
17 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
18 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c),
19 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2),
20 	BPF_EXIT_INSN(),
21 	},
22 	.result = REJECT,
23 	.errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8",
24 },
25 {
26 	"PTR_TO_STACK store/load - bad alignment on reg",
27 	.insns = {
28 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
29 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10),
30 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
31 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
32 	BPF_EXIT_INSN(),
33 	},
34 	.result = REJECT,
35 	.errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8",
36 },
37 {
38 	"PTR_TO_STACK store/load - out of bounds low",
39 	.insns = {
40 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
41 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000),
42 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
43 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
44 	BPF_EXIT_INSN(),
45 	},
46 	.result = REJECT,
47 	.errstr = "invalid write to stack R1 off=-79992 size=8",
48 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
49 },
50 {
51 	"PTR_TO_STACK store/load - out of bounds high",
52 	.insns = {
53 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
54 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
55 	BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c),
56 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8),
57 	BPF_EXIT_INSN(),
58 	},
59 	.result = REJECT,
60 	.errstr = "invalid write to stack R1 off=0 size=8",
61 },
62 {
63 	"PTR_TO_STACK check high 1",
64 	.insns = {
65 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
66 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1),
67 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
68 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
69 	BPF_EXIT_INSN(),
70 	},
71 	.result = ACCEPT,
72 	.retval = 42,
73 },
74 {
75 	"PTR_TO_STACK check high 2",
76 	.insns = {
77 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
78 	BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42),
79 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1),
80 	BPF_EXIT_INSN(),
81 	},
82 	.result = ACCEPT,
83 	.retval = 42,
84 },
85 {
86 	"PTR_TO_STACK check high 3",
87 	.insns = {
88 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
89 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0),
90 	BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42),
91 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1),
92 	BPF_EXIT_INSN(),
93 	},
94 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
95 	.result_unpriv = REJECT,
96 	.result = ACCEPT,
97 	.retval = 42,
98 },
99 {
100 	"PTR_TO_STACK check high 4",
101 	.insns = {
102 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
103 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0),
104 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
105 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
106 	BPF_EXIT_INSN(),
107 	},
108 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
109 	.errstr = "invalid write to stack R1 off=0 size=1",
110 	.result = REJECT,
111 },
112 {
113 	"PTR_TO_STACK check high 5",
114 	.insns = {
115 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
116 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1),
117 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
118 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
119 	BPF_EXIT_INSN(),
120 	},
121 	.result = REJECT,
122 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
123 	.errstr = "invalid write to stack R1",
124 },
125 {
126 	"PTR_TO_STACK check high 6",
127 	.insns = {
128 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
129 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1),
130 	BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42),
131 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX),
132 	BPF_EXIT_INSN(),
133 	},
134 	.result = REJECT,
135 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
136 	.errstr = "invalid write to stack",
137 },
138 {
139 	"PTR_TO_STACK check high 7",
140 	.insns = {
141 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
142 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1),
143 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1),
144 	BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42),
145 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX),
146 	BPF_EXIT_INSN(),
147 	},
148 	.result = REJECT,
149 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
150 	.errstr = "fp pointer offset",
151 },
152 {
153 	"PTR_TO_STACK check low 1",
154 	.insns = {
155 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
156 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -512),
157 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
158 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
159 	BPF_EXIT_INSN(),
160 	},
161 	.result = ACCEPT,
162 	.retval = 42,
163 },
164 {
165 	"PTR_TO_STACK check low 2",
166 	.insns = {
167 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
168 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513),
169 	BPF_ST_MEM(BPF_B, BPF_REG_1, 1, 42),
170 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 1),
171 	BPF_EXIT_INSN(),
172 	},
173 	.result_unpriv = REJECT,
174 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
175 	.result = ACCEPT,
176 	.retval = 42,
177 },
178 {
179 	"PTR_TO_STACK check low 3",
180 	.insns = {
181 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
182 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513),
183 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
184 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
185 	BPF_EXIT_INSN(),
186 	},
187 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
188 	.errstr = "invalid write to stack R1 off=-513 size=1",
189 	.result = REJECT,
190 },
191 {
192 	"PTR_TO_STACK check low 4",
193 	.insns = {
194 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
195 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, INT_MIN),
196 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
197 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
198 	BPF_EXIT_INSN(),
199 	},
200 	.result = REJECT,
201 	.errstr = "math between fp pointer",
202 },
203 {
204 	"PTR_TO_STACK check low 5",
205 	.insns = {
206 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
207 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)),
208 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
209 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
210 	BPF_EXIT_INSN(),
211 	},
212 	.result = REJECT,
213 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
214 	.errstr = "invalid write to stack",
215 },
216 {
217 	"PTR_TO_STACK check low 6",
218 	.insns = {
219 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
220 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)),
221 	BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42),
222 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN),
223 	BPF_EXIT_INSN(),
224 	},
225 	.result = REJECT,
226 	.errstr = "invalid write to stack",
227 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
228 },
229 {
230 	"PTR_TO_STACK check low 7",
231 	.insns = {
232 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
233 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)),
234 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)),
235 	BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42),
236 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN),
237 	BPF_EXIT_INSN(),
238 	},
239 	.result = REJECT,
240 	.errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
241 	.errstr = "fp pointer offset",
242 },
243 {
244 	"PTR_TO_STACK mixed reg/k, 1",
245 	.insns = {
246 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
247 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3),
248 	BPF_MOV64_IMM(BPF_REG_2, -3),
249 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
250 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
251 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
252 	BPF_EXIT_INSN(),
253 	},
254 	.result = ACCEPT,
255 	.retval = 42,
256 },
257 {
258 	"PTR_TO_STACK mixed reg/k, 2",
259 	.insns = {
260 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
261 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
262 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
263 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3),
264 	BPF_MOV64_IMM(BPF_REG_2, -3),
265 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
266 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
267 	BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
268 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_5, -6),
269 	BPF_EXIT_INSN(),
270 	},
271 	.result = ACCEPT,
272 	.retval = 42,
273 },
274 {
275 	"PTR_TO_STACK mixed reg/k, 3",
276 	.insns = {
277 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
278 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3),
279 	BPF_MOV64_IMM(BPF_REG_2, -3),
280 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
281 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
282 	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
283 	BPF_EXIT_INSN(),
284 	},
285 	.result = ACCEPT,
286 	.retval = -3,
287 },
288 {
289 	"PTR_TO_STACK reg",
290 	.insns = {
291 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
292 	BPF_MOV64_IMM(BPF_REG_2, -3),
293 	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
294 	BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
295 	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
296 	BPF_EXIT_INSN(),
297 	},
298 	.result = ACCEPT,
299 	.retval = 42,
300 },
301 {
302 	"stack pointer arithmetic",
303 	.insns = {
304 	BPF_MOV64_IMM(BPF_REG_1, 4),
305 	BPF_JMP_IMM(BPF_JA, 0, 0, 0),
306 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
307 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
308 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10),
309 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
310 	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
311 	BPF_ST_MEM(0, BPF_REG_2, 4, 0),
312 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
313 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8),
314 	BPF_ST_MEM(0, BPF_REG_2, 4, 0),
315 	BPF_MOV64_IMM(BPF_REG_0, 0),
316 	BPF_EXIT_INSN(),
317 	},
318 	.result = ACCEPT,
319 },
320 {
321 	"store PTR_TO_STACK in R10 to array map using BPF_B",
322 	.insns = {
323 	/* Load pointer to map. */
324 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
325 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
326 	BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
327 	BPF_LD_MAP_FD(BPF_REG_1, 0),
328 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
329 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
330 	BPF_MOV64_IMM(BPF_REG_0, 2),
331 	BPF_EXIT_INSN(),
332 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
333 	/* Copy R10 to R9. */
334 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_10),
335 	/* Pollute other registers with unaligned values. */
336 	BPF_MOV64_IMM(BPF_REG_2, -1),
337 	BPF_MOV64_IMM(BPF_REG_3, -1),
338 	BPF_MOV64_IMM(BPF_REG_4, -1),
339 	BPF_MOV64_IMM(BPF_REG_5, -1),
340 	BPF_MOV64_IMM(BPF_REG_6, -1),
341 	BPF_MOV64_IMM(BPF_REG_7, -1),
342 	BPF_MOV64_IMM(BPF_REG_8, -1),
343 	/* Store both R9 and R10 with BPF_B and read back. */
344 	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, 0),
345 	BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_1, 0),
346 	BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_9, 0),
347 	BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_1, 0),
348 	/* Should read back as same value. */
349 	BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_3, 2),
350 	BPF_MOV64_IMM(BPF_REG_0, 1),
351 	BPF_EXIT_INSN(),
352 	BPF_MOV64_IMM(BPF_REG_0, 42),
353 	BPF_EXIT_INSN(),
354 	},
355 	.fixup_map_array_48b = { 3 },
356 	.result = ACCEPT,
357 	.retval = 42,
358 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
359 },
360