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