bed53b561e0443328c0a82015c38abc56015650a
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / verifier / array_access.c
1 {
2         "valid map access into an array with a constant",
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, 1),
10         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
11         BPF_EXIT_INSN(),
12         },
13         .fixup_map_hash_48b = { 3 },
14         .errstr_unpriv = "R0 leaks addr",
15         .result_unpriv = REJECT,
16         .result = ACCEPT,
17 },
18 {
19         "valid map access into an array with a register",
20         .insns = {
21         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
22         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
23         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
24         BPF_LD_MAP_FD(BPF_REG_1, 0),
25         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
26         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
27         BPF_MOV64_IMM(BPF_REG_1, 4),
28         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
29         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
30         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
31         BPF_EXIT_INSN(),
32         },
33         .fixup_map_hash_48b = { 3 },
34         .errstr_unpriv = "R0 leaks addr",
35         .result_unpriv = REJECT,
36         .result = ACCEPT,
37         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
38 },
39 {
40         "valid map access into an array with a variable",
41         .insns = {
42         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
43         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
44         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
45         BPF_LD_MAP_FD(BPF_REG_1, 0),
46         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
47         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
48         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
49         BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
50         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
51         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
52         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
53         BPF_EXIT_INSN(),
54         },
55         .fixup_map_hash_48b = { 3 },
56         .errstr_unpriv = "R0 leaks addr",
57         .result_unpriv = REJECT,
58         .result = ACCEPT,
59         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
60 },
61 {
62         "valid map access into an array with a signed variable",
63         .insns = {
64         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
65         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
66         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
67         BPF_LD_MAP_FD(BPF_REG_1, 0),
68         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
69         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
70         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
71         BPF_JMP32_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
72         BPF_MOV32_IMM(BPF_REG_1, 0),
73         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
74         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
75         BPF_MOV32_IMM(BPF_REG_1, 0),
76         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
77         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
78         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
79         BPF_EXIT_INSN(),
80         },
81         .fixup_map_hash_48b = { 3 },
82         .errstr_unpriv = "R0 leaks addr",
83         .result_unpriv = REJECT,
84         .result = ACCEPT,
85         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
86 },
87 {
88         "invalid map access into an array with a constant",
89         .insns = {
90         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
91         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
92         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
93         BPF_LD_MAP_FD(BPF_REG_1, 0),
94         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
95         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
96         BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
97                    offsetof(struct test_val, foo)),
98         BPF_EXIT_INSN(),
99         },
100         .fixup_map_hash_48b = { 3 },
101         .errstr = "invalid access to map value, value_size=48 off=48 size=8",
102         .result = REJECT,
103 },
104 {
105         "invalid map access into an array with a register",
106         .insns = {
107         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
108         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
109         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
110         BPF_LD_MAP_FD(BPF_REG_1, 0),
111         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
112         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
113         BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
114         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
115         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
116         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
117         BPF_EXIT_INSN(),
118         },
119         .fixup_map_hash_48b = { 3 },
120         .errstr = "R0 min value is outside of the allowed memory range",
121         .result = REJECT,
122         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
123 },
124 {
125         "invalid map access into an array with a variable",
126         .insns = {
127         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
128         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
129         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
130         BPF_LD_MAP_FD(BPF_REG_1, 0),
131         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
132         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
133         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
134         BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
135         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
136         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
137         BPF_EXIT_INSN(),
138         },
139         .fixup_map_hash_48b = { 3 },
140         .errstr = "R0 unbounded memory access, make sure to bounds check any such access",
141         .result = REJECT,
142         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
143 },
144 {
145         "invalid map access into an array with no floor check",
146         .insns = {
147         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
148         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
149         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
150         BPF_LD_MAP_FD(BPF_REG_1, 0),
151         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
152         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
153         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
154         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
155         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
156         BPF_MOV32_IMM(BPF_REG_1, 0),
157         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
158         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
159         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
160         BPF_EXIT_INSN(),
161         },
162         .fixup_map_hash_48b = { 3 },
163         .errstr_unpriv = "R0 leaks addr",
164         .errstr = "R0 unbounded memory access",
165         .result_unpriv = REJECT,
166         .result = REJECT,
167         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
168 },
169 {
170         "invalid map access into an array with a invalid max check",
171         .insns = {
172         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
173         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
174         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
175         BPF_LD_MAP_FD(BPF_REG_1, 0),
176         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
177         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
178         BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
179         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
180         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
181         BPF_MOV32_IMM(BPF_REG_1, 0),
182         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
183         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
184         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
185         BPF_EXIT_INSN(),
186         },
187         .fixup_map_hash_48b = { 3 },
188         .errstr_unpriv = "R0 leaks addr",
189         .errstr = "invalid access to map value, value_size=48 off=44 size=8",
190         .result_unpriv = REJECT,
191         .result = REJECT,
192         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
193 },
194 {
195         "invalid map access into an array with a invalid max check",
196         .insns = {
197         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
198         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
199         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
200         BPF_LD_MAP_FD(BPF_REG_1, 0),
201         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
202         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
203         BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
204         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
205         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
206         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
207         BPF_LD_MAP_FD(BPF_REG_1, 0),
208         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
209         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
210         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
211         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
212                     offsetof(struct test_val, foo)),
213         BPF_EXIT_INSN(),
214         },
215         .fixup_map_hash_48b = { 3, 11 },
216         .errstr = "R0 pointer += pointer",
217         .result = REJECT,
218         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
219 },
220 {
221         "valid read map access into a read-only array 1",
222         .insns = {
223         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
224         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
225         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
226         BPF_LD_MAP_FD(BPF_REG_1, 0),
227         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
228         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
229         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
230         BPF_EXIT_INSN(),
231         },
232         .fixup_map_array_ro = { 3 },
233         .result = ACCEPT,
234         .retval = 28,
235 },
236 {
237         "valid read map access into a read-only array 2",
238         .insns = {
239         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
240         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
241         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
242         BPF_LD_MAP_FD(BPF_REG_1, 0),
243         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
244         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
245
246         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
247         BPF_MOV64_IMM(BPF_REG_2, 4),
248         BPF_MOV64_IMM(BPF_REG_3, 0),
249         BPF_MOV64_IMM(BPF_REG_4, 0),
250         BPF_MOV64_IMM(BPF_REG_5, 0),
251         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
252                      BPF_FUNC_csum_diff),
253         BPF_EXIT_INSN(),
254         },
255         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
256         .fixup_map_array_ro = { 3 },
257         .result = ACCEPT,
258         .retval = -29,
259 },
260 {
261         "invalid write map access into a read-only array 1",
262         .insns = {
263         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
264         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
265         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
266         BPF_LD_MAP_FD(BPF_REG_1, 0),
267         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
268         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
269         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
270         BPF_EXIT_INSN(),
271         },
272         .fixup_map_array_ro = { 3 },
273         .result = REJECT,
274         .errstr = "write into map forbidden",
275 },
276 {
277         "invalid write map access into a read-only array 2",
278         .insns = {
279         BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
280         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
281         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
282         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
283         BPF_LD_MAP_FD(BPF_REG_1, 0),
284         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
285         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
286         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
287         BPF_MOV64_IMM(BPF_REG_2, 0),
288         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
289         BPF_MOV64_IMM(BPF_REG_4, 8),
290         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
291                      BPF_FUNC_skb_load_bytes),
292         BPF_EXIT_INSN(),
293         },
294         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
295         .fixup_map_array_ro = { 4 },
296         .result = REJECT,
297         .errstr = "write into map forbidden",
298 },
299 {
300         "valid write map access into a write-only array 1",
301         .insns = {
302         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
303         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
304         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
305         BPF_LD_MAP_FD(BPF_REG_1, 0),
306         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
307         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
308         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
309         BPF_MOV64_IMM(BPF_REG_0, 1),
310         BPF_EXIT_INSN(),
311         },
312         .fixup_map_array_wo = { 3 },
313         .result = ACCEPT,
314         .retval = 1,
315 },
316 {
317         "valid write map access into a write-only array 2",
318         .insns = {
319         BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
320         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
321         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
322         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
323         BPF_LD_MAP_FD(BPF_REG_1, 0),
324         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
325         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
326         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
327         BPF_MOV64_IMM(BPF_REG_2, 0),
328         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
329         BPF_MOV64_IMM(BPF_REG_4, 8),
330         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
331                      BPF_FUNC_skb_load_bytes),
332         BPF_EXIT_INSN(),
333         },
334         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
335         .fixup_map_array_wo = { 4 },
336         .result = ACCEPT,
337         .retval = 0,
338 },
339 {
340         "invalid read map access into a write-only array 1",
341         .insns = {
342         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
343         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
344         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
345         BPF_LD_MAP_FD(BPF_REG_1, 0),
346         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
347         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
348         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
349         BPF_EXIT_INSN(),
350         },
351         .fixup_map_array_wo = { 3 },
352         .result = REJECT,
353         .errstr = "read from map forbidden",
354 },
355 {
356         "invalid read map access into a write-only array 2",
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
365         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
366         BPF_MOV64_IMM(BPF_REG_2, 4),
367         BPF_MOV64_IMM(BPF_REG_3, 0),
368         BPF_MOV64_IMM(BPF_REG_4, 0),
369         BPF_MOV64_IMM(BPF_REG_5, 0),
370         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
371                      BPF_FUNC_csum_diff),
372         BPF_EXIT_INSN(),
373         },
374         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
375         .fixup_map_array_wo = { 3 },
376         .result = REJECT,
377         .errstr = "read from map forbidden",
378 },