2 "subtraction bounds (map value) variant 1",
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),
19 BPF_MOV64_IMM(BPF_REG_0
, 0),
22 .fixup_map_hash_8b
= { 3 },
23 .errstr
= "R0 max value is outside of the array range",
27 "subtraction bounds (map value) variant 2",
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),
43 BPF_MOV64_IMM(BPF_REG_0
, 0),
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",
52 "check subtraction on pointers for unpriv",
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),
69 BPF_STX_MEM(BPF_DW
, BPF_REG_0
, BPF_REG_9
, 0),
70 BPF_MOV64_IMM(BPF_REG_0
, 0),
73 .fixup_map_hash_8b
= { 1, 9 },
75 .result_unpriv
= REJECT
,
76 .errstr_unpriv
= "R9 pointer -= pointer prohibited",
79 "bounds check based on zero-extended MOV",
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),
90 BPF_ALU64_IMM(BPF_RSH
, BPF_REG_2
, 32),
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),
96 BPF_MOV64_IMM(BPF_REG_0
, 0),
99 .fixup_map_hash_8b
= { 3 },
103 "bounds check based on sign-extended MOV. test1",
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),
120 BPF_MOV64_IMM(BPF_REG_0
, 0),
123 .fixup_map_hash_8b
= { 3 },
124 .errstr
= "map_value pointer and 4294967295",
128 "bounds check based on sign-extended MOV. test2",
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),
145 BPF_MOV64_IMM(BPF_REG_0
, 0),
148 .fixup_map_hash_8b
= { 3 },
149 .errstr
= "R0 min value is outside of the array range",
153 "bounds check based on reg_off + var_off + insn_off. test1",
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),
171 .fixup_map_hash_8b
= { 4 },
172 .errstr
= "value_size=8 off=1073741825",
174 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
177 "bounds check based on reg_off + var_off + insn_off. test2",
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),
195 .fixup_map_hash_8b
= { 4 },
196 .errstr
= "value 1073741823",
198 .prog_type
= BPF_PROG_TYPE_SCHED_CLS
,
201 "bounds check after truncation of non-boundary-crossing range",
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),
221 BPF_ALU64_IMM(BPF_RSH
, BPF_REG_1
, 8),
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),
227 BPF_MOV64_IMM(BPF_REG_0
, 0),
230 .fixup_map_hash_8b
= { 3 },
234 "bounds check after truncation of boundary-crossing range (1)",
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]
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]
255 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_1
, 0xffffff80 >> 1),
257 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
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),
265 BPF_MOV64_IMM(BPF_REG_0
, 0),
268 .fixup_map_hash_8b
= { 3 },
269 /* not actually fully unbounded, but the bound is very high */
270 .errstr
= "R0 unbounded memory access",
274 "bounds check after truncation of boundary-crossing range (2)",
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
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]
297 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_1
, 0xffffff80 >> 1),
299 * [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
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),
307 BPF_MOV64_IMM(BPF_REG_0
, 0),
310 .fixup_map_hash_8b
= { 3 },
311 /* not actually fully unbounded, but the bound is very high */
312 .errstr
= "R0 unbounded memory access",
316 "bounds check after wrapping 32-bit addition",
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),
329 BPF_ALU32_IMM(BPF_ADD
, BPF_REG_1
, 2),
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),
335 BPF_MOV64_IMM(BPF_REG_0
, 0),
338 .fixup_map_hash_8b
= { 3 },
342 "bounds check after shift with oversized count operand",
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),
361 BPF_MOV64_IMM(BPF_REG_0
, 0),
364 .fixup_map_hash_8b
= { 3 },
365 .errstr
= "R0 max value is outside of the array range",
369 "bounds check after right shift of maybe-negative number",
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),
390 BPF_MOV64_IMM(BPF_REG_0
, 0),
393 .fixup_map_hash_8b
= { 3 },
394 .errstr
= "R0 unbounded memory access",
398 "bounds check after 32-bit right shift with 64-bit input",
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),
407 BPF_MOV64_IMM(BPF_REG_1
, 2),
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
),
417 BPF_LDX_MEM(BPF_B
, BPF_REG_0
, BPF_REG_0
, 0),
419 BPF_MOV64_IMM(BPF_REG_0
, 0),
422 .fixup_map_hash_8b
= { 3 },
423 .errstr
= "R0 invalid mem access",
427 "bounds check map access with off+size signed 32bit overflow. test1",
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),
436 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_0
, 0x7ffffffe),
437 BPF_LDX_MEM(BPF_DW
, BPF_REG_0
, BPF_REG_0
, 0),
441 .fixup_map_hash_8b
= { 3 },
442 .errstr
= "map_value pointer and 2147483646",
446 "bounds check map access with off+size signed 32bit overflow. test2",
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),
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),
462 .fixup_map_hash_8b
= { 3 },
463 .errstr
= "pointer offset 1073741822",
464 .errstr_unpriv
= "R0 pointer arithmetic of map value goes out of range",
468 "bounds check map access with off+size signed 32bit overflow. test3",
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),
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),
483 .fixup_map_hash_8b
= { 3 },
484 .errstr
= "pointer offset -1073741822",
485 .errstr_unpriv
= "R0 pointer arithmetic of map value goes out of range",
489 "bounds check map access with off+size signed 32bit overflow. test4",
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),
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),
505 .fixup_map_hash_8b
= { 3 },
506 .errstr
= "map_value pointer and 1000000000000",