Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1{
  2	"subtraction bounds (map value) variant 1",
  3	.insns = {
  4	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  5	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  6	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  7	BPF_LD_MAP_FD(BPF_REG_1, 0),
  8	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  9	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
 10	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 11	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
 12	BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
 13	BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
 14	BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
 15	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
 16	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 17	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 18	BPF_EXIT_INSN(),
 19	BPF_MOV64_IMM(BPF_REG_0, 0),
 20	BPF_EXIT_INSN(),
 21	},
 22	.fixup_map_hash_8b = { 3 },
 23	.errstr = "R0 max value is outside of the array range",
 24	.result = REJECT,
 25},
 26{
 27	"subtraction bounds (map value) variant 2",
 28	.insns = {
 29	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 30	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 31	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 32	BPF_LD_MAP_FD(BPF_REG_1, 0),
 33	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 34	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
 35	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
 36	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
 37	BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
 38	BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
 39	BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
 40	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
 41	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 42	BPF_EXIT_INSN(),
 43	BPF_MOV64_IMM(BPF_REG_0, 0),
 44	BPF_EXIT_INSN(),
 45	},
 46	.fixup_map_hash_8b = { 3 },
 47	.errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
 48	.errstr_unpriv = "R1 has unknown scalar with mixed signed bounds",
 49	.result = REJECT,
 50},
 51{
 52	"check subtraction on pointers for unpriv",
 53	.insns = {
 54	BPF_MOV64_IMM(BPF_REG_0, 0),
 55	BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
 56	BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
 57	BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
 58	BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 9),
 59	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 60	BPF_MOV64_REG(BPF_REG_9, BPF_REG_FP),
 61	BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_0),
 62	BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
 63	BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
 64	BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
 65	BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 0),
 66	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 67	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
 68	BPF_EXIT_INSN(),
 69	BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
 70	BPF_MOV64_IMM(BPF_REG_0, 0),
 71	BPF_EXIT_INSN(),
 72	},
 73	.fixup_map_hash_8b = { 1, 9 },
 74	.result = ACCEPT,
 75	.result_unpriv = REJECT,
 76	.errstr_unpriv = "R9 pointer -= pointer prohibited",
 77},
 78{
 79	"bounds check based on zero-extended MOV",
 80	.insns = {
 81	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 82	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
 83	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
 84	BPF_LD_MAP_FD(BPF_REG_1, 0),
 85	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 86	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
 87	/* r2 = 0x0000'0000'ffff'ffff */
 88	BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
 89	/* r2 = 0 */
 90	BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
 91	/* no-op */
 92	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
 93	/* access at offset 0 */
 94	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
 95	/* exit */
 96	BPF_MOV64_IMM(BPF_REG_0, 0),
 97	BPF_EXIT_INSN(),
 98	},
 99	.fixup_map_hash_8b = { 3 },
100	.result = ACCEPT
101},
102{
103	"bounds check based on sign-extended MOV. test1",
104	.insns = {
105	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
106	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
107	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
108	BPF_LD_MAP_FD(BPF_REG_1, 0),
109	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
110	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
111	/* r2 = 0xffff'ffff'ffff'ffff */
112	BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
113	/* r2 = 0xffff'ffff */
114	BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
115	/* r0 = <oob pointer> */
116	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
117	/* access to OOB pointer */
118	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
119	/* exit */
120	BPF_MOV64_IMM(BPF_REG_0, 0),
121	BPF_EXIT_INSN(),
122	},
123	.fixup_map_hash_8b = { 3 },
124	.errstr = "map_value pointer and 4294967295",
125	.result = REJECT
126},
127{
128	"bounds check based on sign-extended MOV. test2",
129	.insns = {
130	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
131	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
132	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
133	BPF_LD_MAP_FD(BPF_REG_1, 0),
134	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
135	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
136	/* r2 = 0xffff'ffff'ffff'ffff */
137	BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
138	/* r2 = 0xfff'ffff */
139	BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
140	/* r0 = <oob pointer> */
141	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
142	/* access to OOB pointer */
143	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
144	/* exit */
145	BPF_MOV64_IMM(BPF_REG_0, 0),
146	BPF_EXIT_INSN(),
147	},
148	.fixup_map_hash_8b = { 3 },
149	.errstr = "R0 min value is outside of the array range",
150	.result = REJECT
151},
152{
153	"bounds check based on reg_off + var_off + insn_off. test1",
154	.insns = {
155	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
156		    offsetof(struct __sk_buff, mark)),
157	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
158	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
159	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
160	BPF_LD_MAP_FD(BPF_REG_1, 0),
161	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
162	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
163	BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
164	BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
165	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
166	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
167	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
168	BPF_MOV64_IMM(BPF_REG_0, 0),
169	BPF_EXIT_INSN(),
170	},
171	.fixup_map_hash_8b = { 4 },
172	.errstr = "value_size=8 off=1073741825",
173	.result = REJECT,
174	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
175},
176{
177	"bounds check based on reg_off + var_off + insn_off. test2",
178	.insns = {
179	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
180		    offsetof(struct __sk_buff, mark)),
181	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
182	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
183	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
184	BPF_LD_MAP_FD(BPF_REG_1, 0),
185	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
186	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
187	BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
188	BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
189	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
190	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
191	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
192	BPF_MOV64_IMM(BPF_REG_0, 0),
193	BPF_EXIT_INSN(),
194	},
195	.fixup_map_hash_8b = { 4 },
196	.errstr = "value 1073741823",
197	.result = REJECT,
198	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
199},
200{
201	"bounds check after truncation of non-boundary-crossing range",
202	.insns = {
203	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
204	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
205	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
206	BPF_LD_MAP_FD(BPF_REG_1, 0),
207	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
208	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
209	/* r1 = [0x00, 0xff] */
210	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
211	BPF_MOV64_IMM(BPF_REG_2, 1),
212	/* r2 = 0x10'0000'0000 */
213	BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
214	/* r1 = [0x10'0000'0000, 0x10'0000'00ff] */
215	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
216	/* r1 = [0x10'7fff'ffff, 0x10'8000'00fe] */
217	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
218	/* r1 = [0x00, 0xff] */
219	BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
220	/* r1 = 0 */
221	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
222	/* no-op */
223	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
224	/* access at offset 0 */
225	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
226	/* exit */
227	BPF_MOV64_IMM(BPF_REG_0, 0),
228	BPF_EXIT_INSN(),
229	},
230	.fixup_map_hash_8b = { 3 },
231	.result = ACCEPT
232},
233{
234	"bounds check after truncation of boundary-crossing range (1)",
235	.insns = {
236	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
237	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
238	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
239	BPF_LD_MAP_FD(BPF_REG_1, 0),
240	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
241	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
242	/* r1 = [0x00, 0xff] */
243	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
244	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
245	/* r1 = [0xffff'ff80, 0x1'0000'007f] */
246	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
247	/* r1 = [0xffff'ff80, 0xffff'ffff] or
248	 *      [0x0000'0000, 0x0000'007f]
249	 */
250	BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
251	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
252	/* r1 = [0x00, 0xff] or
253	 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
254	 */
255	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
256	/* r1 = 0 or
257	 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
258	 */
259	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
260	/* no-op or OOB pointer computation */
261	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
262	/* potentially OOB access */
263	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
264	/* exit */
265	BPF_MOV64_IMM(BPF_REG_0, 0),
266	BPF_EXIT_INSN(),
267	},
268	.fixup_map_hash_8b = { 3 },
269	/* not actually fully unbounded, but the bound is very high */
270	.errstr = "R0 unbounded memory access",
271	.result = REJECT
272},
273{
274	"bounds check after truncation of boundary-crossing range (2)",
275	.insns = {
276	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
277	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
278	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
279	BPF_LD_MAP_FD(BPF_REG_1, 0),
280	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
281	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
282	/* r1 = [0x00, 0xff] */
283	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
284	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
285	/* r1 = [0xffff'ff80, 0x1'0000'007f] */
286	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
287	/* r1 = [0xffff'ff80, 0xffff'ffff] or
288	 *      [0x0000'0000, 0x0000'007f]
289	 * difference to previous test: truncation via MOV32
290	 * instead of ALU32.
291	 */
292	BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
293	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
294	/* r1 = [0x00, 0xff] or
295	 *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
296	 */
297	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
298	/* r1 = 0 or
299	 *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
300	 */
301	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
302	/* no-op or OOB pointer computation */
303	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
304	/* potentially OOB access */
305	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
306	/* exit */
307	BPF_MOV64_IMM(BPF_REG_0, 0),
308	BPF_EXIT_INSN(),
309	},
310	.fixup_map_hash_8b = { 3 },
311	/* not actually fully unbounded, but the bound is very high */
312	.errstr = "R0 unbounded memory access",
313	.result = REJECT
314},
315{
316	"bounds check after wrapping 32-bit addition",
317	.insns = {
318	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
319	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
320	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
321	BPF_LD_MAP_FD(BPF_REG_1, 0),
322	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
323	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
324	/* r1 = 0x7fff'ffff */
325	BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
326	/* r1 = 0xffff'fffe */
327	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
328	/* r1 = 0 */
329	BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
330	/* no-op */
331	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
332	/* access at offset 0 */
333	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
334	/* exit */
335	BPF_MOV64_IMM(BPF_REG_0, 0),
336	BPF_EXIT_INSN(),
337	},
338	.fixup_map_hash_8b = { 3 },
339	.result = ACCEPT
340},
341{
342	"bounds check after shift with oversized count operand",
343	.insns = {
344	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
345	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
346	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
347	BPF_LD_MAP_FD(BPF_REG_1, 0),
348	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
349	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
350	BPF_MOV64_IMM(BPF_REG_2, 32),
351	BPF_MOV64_IMM(BPF_REG_1, 1),
352	/* r1 = (u32)1 << (u32)32 = ? */
353	BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
354	/* r1 = [0x0000, 0xffff] */
355	BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
356	/* computes unknown pointer, potentially OOB */
357	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
358	/* potentially OOB access */
359	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
360	/* exit */
361	BPF_MOV64_IMM(BPF_REG_0, 0),
362	BPF_EXIT_INSN(),
363	},
364	.fixup_map_hash_8b = { 3 },
365	.errstr = "R0 max value is outside of the array range",
366	.result = REJECT
367},
368{
369	"bounds check after right shift of maybe-negative number",
370	.insns = {
371	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
372	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
373	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
374	BPF_LD_MAP_FD(BPF_REG_1, 0),
375	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
376	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
377	/* r1 = [0x00, 0xff] */
378	BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
379	/* r1 = [-0x01, 0xfe] */
380	BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
381	/* r1 = 0 or 0xff'ffff'ffff'ffff */
382	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
383	/* r1 = 0 or 0xffff'ffff'ffff */
384	BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
385	/* computes unknown pointer, potentially OOB */
386	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
387	/* potentially OOB access */
388	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
389	/* exit */
390	BPF_MOV64_IMM(BPF_REG_0, 0),
391	BPF_EXIT_INSN(),
392	},
393	.fixup_map_hash_8b = { 3 },
394	.errstr = "R0 unbounded memory access",
395	.result = REJECT
396},
397{
398	"bounds check after 32-bit right shift with 64-bit input",
399	.insns = {
400	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
401	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
402	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
403	BPF_LD_MAP_FD(BPF_REG_1, 0),
404	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
405	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
406	/* r1 = 2 */
407	BPF_MOV64_IMM(BPF_REG_1, 2),
408	/* r1 = 1<<32 */
409	BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 31),
410	/* r1 = 0 (NOT 2!) */
411	BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 31),
412	/* r1 = 0xffff'fffe (NOT 0!) */
413	BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 2),
414	/* computes OOB pointer */
415	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
416	/* OOB access */
417	BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
418	/* exit */
419	BPF_MOV64_IMM(BPF_REG_0, 0),
420	BPF_EXIT_INSN(),
421	},
422	.fixup_map_hash_8b = { 3 },
423	.errstr = "R0 invalid mem access",
424	.result = REJECT,
425},
426{
427	"bounds check map access with off+size signed 32bit overflow. test1",
428	.insns = {
429	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
430	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
431	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
432	BPF_LD_MAP_FD(BPF_REG_1, 0),
433	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
434	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
435	BPF_EXIT_INSN(),
436	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
437	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
438	BPF_JMP_A(0),
439	BPF_EXIT_INSN(),
440	},
441	.fixup_map_hash_8b = { 3 },
442	.errstr = "map_value pointer and 2147483646",
443	.result = REJECT
444},
445{
446	"bounds check map access with off+size signed 32bit overflow. test2",
447	.insns = {
448	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
449	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
450	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
451	BPF_LD_MAP_FD(BPF_REG_1, 0),
452	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
453	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
454	BPF_EXIT_INSN(),
455	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
456	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
457	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
458	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
459	BPF_JMP_A(0),
460	BPF_EXIT_INSN(),
461	},
462	.fixup_map_hash_8b = { 3 },
463	.errstr = "pointer offset 1073741822",
464	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
465	.result = REJECT
466},
467{
468	"bounds check map access with off+size signed 32bit overflow. test3",
469	.insns = {
470	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
471	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
472	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
473	BPF_LD_MAP_FD(BPF_REG_1, 0),
474	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
475	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
476	BPF_EXIT_INSN(),
477	BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
478	BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
479	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
480	BPF_JMP_A(0),
481	BPF_EXIT_INSN(),
482	},
483	.fixup_map_hash_8b = { 3 },
484	.errstr = "pointer offset -1073741822",
485	.errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
486	.result = REJECT
487},
488{
489	"bounds check map access with off+size signed 32bit overflow. test4",
490	.insns = {
491	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
492	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
493	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
494	BPF_LD_MAP_FD(BPF_REG_1, 0),
495	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
496	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
497	BPF_EXIT_INSN(),
498	BPF_MOV64_IMM(BPF_REG_1, 1000000),
499	BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
500	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
501	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
502	BPF_JMP_A(0),
503	BPF_EXIT_INSN(),
504	},
505	.fixup_map_hash_8b = { 3 },
506	.errstr = "map_value pointer and 1000000000000",
507	.result = REJECT
508},