Merge branches 'acpi-pm' and 'acpi-docs'
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / verifier / bounds.c
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 allowed memory 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 allowed memory 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, 8),
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         /* error on OOB pointer computation */
257         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
258         /* exit */
259         BPF_MOV64_IMM(BPF_REG_0, 0),
260         BPF_EXIT_INSN(),
261         },
262         .fixup_map_hash_8b = { 3 },
263         /* not actually fully unbounded, but the bound is very high */
264         .errstr = "value -4294967168 makes map_value pointer be out of bounds",
265         .result = REJECT,
266 },
267 {
268         "bounds check after truncation of boundary-crossing range (2)",
269         .insns = {
270         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
271         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
272         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
273         BPF_LD_MAP_FD(BPF_REG_1, 0),
274         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
275         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
276         /* r1 = [0x00, 0xff] */
277         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
278         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
279         /* r1 = [0xffff'ff80, 0x1'0000'007f] */
280         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
281         /* r1 = [0xffff'ff80, 0xffff'ffff] or
282          *      [0x0000'0000, 0x0000'007f]
283          * difference to previous test: truncation via MOV32
284          * instead of ALU32.
285          */
286         BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
287         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
288         /* r1 = [0x00, 0xff] or
289          *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
290          */
291         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
292         /* error on OOB pointer computation */
293         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
294         /* exit */
295         BPF_MOV64_IMM(BPF_REG_0, 0),
296         BPF_EXIT_INSN(),
297         },
298         .fixup_map_hash_8b = { 3 },
299         .errstr = "value -4294967168 makes map_value pointer be out of bounds",
300         .result = REJECT,
301 },
302 {
303         "bounds check after wrapping 32-bit addition",
304         .insns = {
305         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
306         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
307         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
308         BPF_LD_MAP_FD(BPF_REG_1, 0),
309         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
310         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
311         /* r1 = 0x7fff'ffff */
312         BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
313         /* r1 = 0xffff'fffe */
314         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
315         /* r1 = 0 */
316         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
317         /* no-op */
318         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
319         /* access at offset 0 */
320         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
321         /* exit */
322         BPF_MOV64_IMM(BPF_REG_0, 0),
323         BPF_EXIT_INSN(),
324         },
325         .fixup_map_hash_8b = { 3 },
326         .result = ACCEPT
327 },
328 {
329         "bounds check after shift with oversized count operand",
330         .insns = {
331         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
332         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
333         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
334         BPF_LD_MAP_FD(BPF_REG_1, 0),
335         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
336         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
337         BPF_MOV64_IMM(BPF_REG_2, 32),
338         BPF_MOV64_IMM(BPF_REG_1, 1),
339         /* r1 = (u32)1 << (u32)32 = ? */
340         BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
341         /* r1 = [0x0000, 0xffff] */
342         BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
343         /* computes unknown pointer, potentially OOB */
344         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
345         /* potentially OOB access */
346         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
347         /* exit */
348         BPF_MOV64_IMM(BPF_REG_0, 0),
349         BPF_EXIT_INSN(),
350         },
351         .fixup_map_hash_8b = { 3 },
352         .errstr = "R0 max value is outside of the allowed memory range",
353         .result = REJECT
354 },
355 {
356         "bounds check after right shift of maybe-negative number",
357         .insns = {
358         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
359         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
360         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
361         BPF_LD_MAP_FD(BPF_REG_1, 0),
362         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
363         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
364         /* r1 = [0x00, 0xff] */
365         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
366         /* r1 = [-0x01, 0xfe] */
367         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
368         /* r1 = 0 or 0xff'ffff'ffff'ffff */
369         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
370         /* r1 = 0 or 0xffff'ffff'ffff */
371         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
372         /* computes unknown pointer, potentially OOB */
373         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
374         /* potentially OOB access */
375         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
376         /* exit */
377         BPF_MOV64_IMM(BPF_REG_0, 0),
378         BPF_EXIT_INSN(),
379         },
380         .fixup_map_hash_8b = { 3 },
381         .errstr = "R0 unbounded memory access",
382         .result = REJECT
383 },
384 {
385         "bounds check after 32-bit right shift with 64-bit input",
386         .insns = {
387         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
388         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
389         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
390         BPF_LD_MAP_FD(BPF_REG_1, 0),
391         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
392         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
393         /* r1 = 2 */
394         BPF_MOV64_IMM(BPF_REG_1, 2),
395         /* r1 = 1<<32 */
396         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 31),
397         /* r1 = 0 (NOT 2!) */
398         BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 31),
399         /* r1 = 0xffff'fffe (NOT 0!) */
400         BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 2),
401         /* error on computing OOB pointer */
402         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
403         /* exit */
404         BPF_MOV64_IMM(BPF_REG_0, 0),
405         BPF_EXIT_INSN(),
406         },
407         .fixup_map_hash_8b = { 3 },
408         .errstr = "math between map_value pointer and 4294967294 is not allowed",
409         .result = REJECT,
410 },
411 {
412         "bounds check map access with off+size signed 32bit overflow. test1",
413         .insns = {
414         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
415         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
416         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
417         BPF_LD_MAP_FD(BPF_REG_1, 0),
418         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
419         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
420         BPF_EXIT_INSN(),
421         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
422         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
423         BPF_JMP_A(0),
424         BPF_EXIT_INSN(),
425         },
426         .fixup_map_hash_8b = { 3 },
427         .errstr = "map_value pointer and 2147483646",
428         .result = REJECT
429 },
430 {
431         "bounds check map access with off+size signed 32bit overflow. test2",
432         .insns = {
433         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
434         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
435         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
436         BPF_LD_MAP_FD(BPF_REG_1, 0),
437         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
438         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
439         BPF_EXIT_INSN(),
440         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
441         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
442         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
443         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
444         BPF_JMP_A(0),
445         BPF_EXIT_INSN(),
446         },
447         .fixup_map_hash_8b = { 3 },
448         .errstr = "pointer offset 1073741822",
449         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
450         .result = REJECT
451 },
452 {
453         "bounds check map access with off+size signed 32bit overflow. test3",
454         .insns = {
455         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
456         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
457         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
458         BPF_LD_MAP_FD(BPF_REG_1, 0),
459         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
460         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
461         BPF_EXIT_INSN(),
462         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
463         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
464         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
465         BPF_JMP_A(0),
466         BPF_EXIT_INSN(),
467         },
468         .fixup_map_hash_8b = { 3 },
469         .errstr = "pointer offset -1073741822",
470         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
471         .result = REJECT
472 },
473 {
474         "bounds check map access with off+size signed 32bit overflow. test4",
475         .insns = {
476         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
477         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
478         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
479         BPF_LD_MAP_FD(BPF_REG_1, 0),
480         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
481         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
482         BPF_EXIT_INSN(),
483         BPF_MOV64_IMM(BPF_REG_1, 1000000),
484         BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
485         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
486         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
487         BPF_JMP_A(0),
488         BPF_EXIT_INSN(),
489         },
490         .fixup_map_hash_8b = { 3 },
491         .errstr = "map_value pointer and 1000000000000",
492         .result = REJECT
493 },
494 {
495         "bounds check mixed 32bit and 64bit arithmetic. test1",
496         .insns = {
497         BPF_MOV64_IMM(BPF_REG_0, 0),
498         BPF_MOV64_IMM(BPF_REG_1, -1),
499         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
500         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
501         /* r1 = 0xffffFFFF00000001 */
502         BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 1, 3),
503         /* check ALU64 op keeps 32bit bounds */
504         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
505         BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 2, 1),
506         BPF_JMP_A(1),
507         /* invalid ldx if bounds are lost above */
508         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
509         BPF_EXIT_INSN(),
510         },
511         .result = ACCEPT
512 },
513 {
514         "bounds check mixed 32bit and 64bit arithmetic. test2",
515         .insns = {
516         BPF_MOV64_IMM(BPF_REG_0, 0),
517         BPF_MOV64_IMM(BPF_REG_1, -1),
518         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
519         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
520         /* r1 = 0xffffFFFF00000001 */
521         BPF_MOV64_IMM(BPF_REG_2, 3),
522         /* r1 = 0x2 */
523         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
524         /* check ALU32 op zero extends 64bit bounds */
525         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 1),
526         BPF_JMP_A(1),
527         /* invalid ldx if bounds are lost above */
528         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
529         BPF_EXIT_INSN(),
530         },
531         .result = ACCEPT
532 },
533 {
534         "assigning 32bit bounds to 64bit for wA = 0, wB = wA",
535         .insns = {
536         BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
537                     offsetof(struct __sk_buff, data_end)),
538         BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
539                     offsetof(struct __sk_buff, data)),
540         BPF_MOV32_IMM(BPF_REG_9, 0),
541         BPF_MOV32_REG(BPF_REG_2, BPF_REG_9),
542         BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
543         BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_2),
544         BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
545         BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
546         BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_8, 1),
547         BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_6, 0),
548         BPF_MOV64_IMM(BPF_REG_0, 0),
549         BPF_EXIT_INSN(),
550         },
551         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
552         .result = ACCEPT,
553         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
554 },
555 {
556         "bounds check for reg = 0, reg xor 1",
557         .insns = {
558         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
559         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
560         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
561         BPF_LD_MAP_FD(BPF_REG_1, 0),
562         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
563         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
564         BPF_EXIT_INSN(),
565         BPF_MOV64_IMM(BPF_REG_1, 0),
566         BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 1),
567         BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
568         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
569         BPF_MOV64_IMM(BPF_REG_0, 0),
570         BPF_EXIT_INSN(),
571         },
572         .fixup_map_hash_8b = { 3 },
573         .result = ACCEPT,
574 },
575 {
576         "bounds check for reg32 = 0, reg32 xor 1",
577         .insns = {
578         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
579         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
580         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
581         BPF_LD_MAP_FD(BPF_REG_1, 0),
582         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
583         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
584         BPF_EXIT_INSN(),
585         BPF_MOV32_IMM(BPF_REG_1, 0),
586         BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 1),
587         BPF_JMP32_IMM(BPF_JNE, BPF_REG_1, 0, 1),
588         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
589         BPF_MOV64_IMM(BPF_REG_0, 0),
590         BPF_EXIT_INSN(),
591         },
592         .fixup_map_hash_8b = { 3 },
593         .result = ACCEPT,
594 },
595 {
596         "bounds check for reg = 2, reg xor 3",
597         .insns = {
598         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
599         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
600         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
601         BPF_LD_MAP_FD(BPF_REG_1, 0),
602         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
603         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
604         BPF_EXIT_INSN(),
605         BPF_MOV64_IMM(BPF_REG_1, 2),
606         BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
607         BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0, 1),
608         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
609         BPF_MOV64_IMM(BPF_REG_0, 0),
610         BPF_EXIT_INSN(),
611         },
612         .fixup_map_hash_8b = { 3 },
613         .result = ACCEPT,
614 },
615 {
616         "bounds check for reg = any, reg xor 3",
617         .insns = {
618         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
619         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
620         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
621         BPF_LD_MAP_FD(BPF_REG_1, 0),
622         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
623         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
624         BPF_EXIT_INSN(),
625         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
626         BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
627         BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
628         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
629         BPF_MOV64_IMM(BPF_REG_0, 0),
630         BPF_EXIT_INSN(),
631         },
632         .fixup_map_hash_8b = { 3 },
633         .result = REJECT,
634         .errstr = "invalid access to map value",
635         .errstr_unpriv = "invalid access to map value",
636 },
637 {
638         "bounds check for reg32 = any, reg32 xor 3",
639         .insns = {
640         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
641         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
642         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
643         BPF_LD_MAP_FD(BPF_REG_1, 0),
644         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
645         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
646         BPF_EXIT_INSN(),
647         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
648         BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 3),
649         BPF_JMP32_IMM(BPF_JNE, BPF_REG_1, 0, 1),
650         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
651         BPF_MOV64_IMM(BPF_REG_0, 0),
652         BPF_EXIT_INSN(),
653         },
654         .fixup_map_hash_8b = { 3 },
655         .result = REJECT,
656         .errstr = "invalid access to map value",
657         .errstr_unpriv = "invalid access to map value",
658 },
659 {
660         "bounds check for reg > 0, reg xor 3",
661         .insns = {
662         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
663         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
664         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
665         BPF_LD_MAP_FD(BPF_REG_1, 0),
666         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
667         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
668         BPF_EXIT_INSN(),
669         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
670         BPF_JMP_IMM(BPF_JLE, BPF_REG_1, 0, 3),
671         BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
672         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 1),
673         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
674         BPF_MOV64_IMM(BPF_REG_0, 0),
675         BPF_EXIT_INSN(),
676         },
677         .fixup_map_hash_8b = { 3 },
678         .result = ACCEPT,
679 },
680 {
681         "bounds check for reg32 > 0, reg32 xor 3",
682         .insns = {
683         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
684         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
685         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
686         BPF_LD_MAP_FD(BPF_REG_1, 0),
687         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
688         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
689         BPF_EXIT_INSN(),
690         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
691         BPF_JMP32_IMM(BPF_JLE, BPF_REG_1, 0, 3),
692         BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 3),
693         BPF_JMP32_IMM(BPF_JGE, BPF_REG_1, 0, 1),
694         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
695         BPF_MOV64_IMM(BPF_REG_0, 0),
696         BPF_EXIT_INSN(),
697         },
698         .fixup_map_hash_8b = { 3 },
699         .result = ACCEPT,
700 },
701 {
702         "bounds checks after 32-bit truncation. test 1",
703         .insns = {
704         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
705         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
706         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
707         BPF_LD_MAP_FD(BPF_REG_1, 0),
708         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
709         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
710         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
711         /* This used to reduce the max bound to 0x7fffffff */
712         BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
713         BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0x7fffffff, 1),
714         BPF_MOV64_IMM(BPF_REG_0, 0),
715         BPF_EXIT_INSN(),
716         },
717         .fixup_map_hash_8b = { 3 },
718         .errstr_unpriv = "R0 leaks addr",
719         .result_unpriv = REJECT,
720         .result = ACCEPT,
721 },
722 {
723         "bounds checks after 32-bit truncation. test 2",
724         .insns = {
725         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
726         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
727         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
728         BPF_LD_MAP_FD(BPF_REG_1, 0),
729         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
730         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
731         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
732         BPF_JMP_IMM(BPF_JSLT, BPF_REG_1, 1, 1),
733         BPF_JMP32_IMM(BPF_JSLT, BPF_REG_1, 0, 1),
734         BPF_MOV64_IMM(BPF_REG_0, 0),
735         BPF_EXIT_INSN(),
736         },
737         .fixup_map_hash_8b = { 3 },
738         .errstr_unpriv = "R0 leaks addr",
739         .result_unpriv = REJECT,
740         .result = ACCEPT,
741 },