OSDN Git Service

drm: Fix HDCP failures when SRM fw is missing
[tomoyo/tomoyo-test1.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 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         /* error on OOB pointer computation */
261         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
262         /* exit */
263         BPF_MOV64_IMM(BPF_REG_0, 0),
264         BPF_EXIT_INSN(),
265         },
266         .fixup_map_hash_8b = { 3 },
267         /* not actually fully unbounded, but the bound is very high */
268         .errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
269         .result = REJECT
270 },
271 {
272         "bounds check after truncation of boundary-crossing range (2)",
273         .insns = {
274         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
275         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
276         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
277         BPF_LD_MAP_FD(BPF_REG_1, 0),
278         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
279         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
280         /* r1 = [0x00, 0xff] */
281         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
282         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
283         /* r1 = [0xffff'ff80, 0x1'0000'007f] */
284         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
285         /* r1 = [0xffff'ff80, 0xffff'ffff] or
286          *      [0x0000'0000, 0x0000'007f]
287          * difference to previous test: truncation via MOV32
288          * instead of ALU32.
289          */
290         BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
291         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
292         /* r1 = [0x00, 0xff] or
293          *      [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
294          */
295         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
296         /* r1 = 0 or
297          *      [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
298          */
299         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
300         /* error on OOB pointer computation */
301         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
302         /* exit */
303         BPF_MOV64_IMM(BPF_REG_0, 0),
304         BPF_EXIT_INSN(),
305         },
306         .fixup_map_hash_8b = { 3 },
307         /* not actually fully unbounded, but the bound is very high */
308         .errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
309         .result = REJECT
310 },
311 {
312         "bounds check after wrapping 32-bit addition",
313         .insns = {
314         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
315         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
316         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
317         BPF_LD_MAP_FD(BPF_REG_1, 0),
318         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
319         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
320         /* r1 = 0x7fff'ffff */
321         BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
322         /* r1 = 0xffff'fffe */
323         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
324         /* r1 = 0 */
325         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
326         /* no-op */
327         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
328         /* access at offset 0 */
329         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
330         /* exit */
331         BPF_MOV64_IMM(BPF_REG_0, 0),
332         BPF_EXIT_INSN(),
333         },
334         .fixup_map_hash_8b = { 3 },
335         .result = ACCEPT
336 },
337 {
338         "bounds check after shift with oversized count operand",
339         .insns = {
340         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
341         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
342         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
343         BPF_LD_MAP_FD(BPF_REG_1, 0),
344         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
345         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
346         BPF_MOV64_IMM(BPF_REG_2, 32),
347         BPF_MOV64_IMM(BPF_REG_1, 1),
348         /* r1 = (u32)1 << (u32)32 = ? */
349         BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
350         /* r1 = [0x0000, 0xffff] */
351         BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
352         /* computes unknown pointer, potentially OOB */
353         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
354         /* potentially OOB access */
355         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
356         /* exit */
357         BPF_MOV64_IMM(BPF_REG_0, 0),
358         BPF_EXIT_INSN(),
359         },
360         .fixup_map_hash_8b = { 3 },
361         .errstr = "R0 max value is outside of the array range",
362         .result = REJECT
363 },
364 {
365         "bounds check after right shift of maybe-negative number",
366         .insns = {
367         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
368         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
369         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
370         BPF_LD_MAP_FD(BPF_REG_1, 0),
371         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
372         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
373         /* r1 = [0x00, 0xff] */
374         BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
375         /* r1 = [-0x01, 0xfe] */
376         BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
377         /* r1 = 0 or 0xff'ffff'ffff'ffff */
378         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
379         /* r1 = 0 or 0xffff'ffff'ffff */
380         BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
381         /* computes unknown pointer, potentially OOB */
382         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
383         /* potentially OOB access */
384         BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
385         /* exit */
386         BPF_MOV64_IMM(BPF_REG_0, 0),
387         BPF_EXIT_INSN(),
388         },
389         .fixup_map_hash_8b = { 3 },
390         .errstr = "R0 unbounded memory access",
391         .result = REJECT
392 },
393 {
394         "bounds check after 32-bit right shift with 64-bit input",
395         .insns = {
396         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
397         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
398         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
399         BPF_LD_MAP_FD(BPF_REG_1, 0),
400         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
401         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
402         /* r1 = 2 */
403         BPF_MOV64_IMM(BPF_REG_1, 2),
404         /* r1 = 1<<32 */
405         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 31),
406         /* r1 = 0 (NOT 2!) */
407         BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 31),
408         /* r1 = 0xffff'fffe (NOT 0!) */
409         BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 2),
410         /* error on computing OOB pointer */
411         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
412         /* exit */
413         BPF_MOV64_IMM(BPF_REG_0, 0),
414         BPF_EXIT_INSN(),
415         },
416         .fixup_map_hash_8b = { 3 },
417         .errstr = "math between map_value pointer and 4294967294 is not allowed",
418         .result = REJECT,
419 },
420 {
421         "bounds check map access with off+size signed 32bit overflow. test1",
422         .insns = {
423         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
424         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
425         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
426         BPF_LD_MAP_FD(BPF_REG_1, 0),
427         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
428         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
429         BPF_EXIT_INSN(),
430         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
431         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
432         BPF_JMP_A(0),
433         BPF_EXIT_INSN(),
434         },
435         .fixup_map_hash_8b = { 3 },
436         .errstr = "map_value pointer and 2147483646",
437         .result = REJECT
438 },
439 {
440         "bounds check map access with off+size signed 32bit overflow. test2",
441         .insns = {
442         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
443         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
444         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
445         BPF_LD_MAP_FD(BPF_REG_1, 0),
446         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
447         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
448         BPF_EXIT_INSN(),
449         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
450         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
451         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
452         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
453         BPF_JMP_A(0),
454         BPF_EXIT_INSN(),
455         },
456         .fixup_map_hash_8b = { 3 },
457         .errstr = "pointer offset 1073741822",
458         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
459         .result = REJECT
460 },
461 {
462         "bounds check map access with off+size signed 32bit overflow. test3",
463         .insns = {
464         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
465         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
466         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
467         BPF_LD_MAP_FD(BPF_REG_1, 0),
468         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
469         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
470         BPF_EXIT_INSN(),
471         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
472         BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
473         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
474         BPF_JMP_A(0),
475         BPF_EXIT_INSN(),
476         },
477         .fixup_map_hash_8b = { 3 },
478         .errstr = "pointer offset -1073741822",
479         .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
480         .result = REJECT
481 },
482 {
483         "bounds check map access with off+size signed 32bit overflow. test4",
484         .insns = {
485         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
486         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
487         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
488         BPF_LD_MAP_FD(BPF_REG_1, 0),
489         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
490         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
491         BPF_EXIT_INSN(),
492         BPF_MOV64_IMM(BPF_REG_1, 1000000),
493         BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
494         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
495         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
496         BPF_JMP_A(0),
497         BPF_EXIT_INSN(),
498         },
499         .fixup_map_hash_8b = { 3 },
500         .errstr = "map_value pointer and 1000000000000",
501         .result = REJECT
502 },
503 {
504         "bounds check mixed 32bit and 64bit arithmatic. test1",
505         .insns = {
506         BPF_MOV64_IMM(BPF_REG_0, 0),
507         BPF_MOV64_IMM(BPF_REG_1, -1),
508         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
509         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
510         /* r1 = 0xffffFFFF00000001 */
511         BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 1, 3),
512         /* check ALU64 op keeps 32bit bounds */
513         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
514         BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 2, 1),
515         BPF_JMP_A(1),
516         /* invalid ldx if bounds are lost above */
517         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
518         BPF_EXIT_INSN(),
519         },
520         .result = ACCEPT
521 },
522 {
523         "bounds check mixed 32bit and 64bit arithmatic. test2",
524         .insns = {
525         BPF_MOV64_IMM(BPF_REG_0, 0),
526         BPF_MOV64_IMM(BPF_REG_1, -1),
527         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
528         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
529         /* r1 = 0xffffFFFF00000001 */
530         BPF_MOV64_IMM(BPF_REG_2, 3),
531         /* r1 = 0x2 */
532         BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
533         /* check ALU32 op zero extends 64bit bounds */
534         BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 1),
535         BPF_JMP_A(1),
536         /* invalid ldx if bounds are lost above */
537         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
538         BPF_EXIT_INSN(),
539         },
540         .result = ACCEPT
541 },