bpf: Allow reads from uninit stack
[platform/kernel/linux-starfive.git] / tools / testing / selftests / bpf / verifier / helper_access_var_len.c
1 {
2         "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
3         .insns = {
4         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
5         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
6         BPF_MOV64_IMM(BPF_REG_0, 0),
7         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
8         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
9         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
10         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
11         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
12         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
13         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
14         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
15         BPF_MOV64_IMM(BPF_REG_2, 16),
16         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
17         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
18         BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
19         BPF_MOV64_IMM(BPF_REG_4, 0),
20         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
21         BPF_MOV64_IMM(BPF_REG_3, 0),
22         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
23         BPF_MOV64_IMM(BPF_REG_0, 0),
24         BPF_EXIT_INSN(),
25         },
26         .result = ACCEPT,
27         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
28 },
29 {
30         "helper access to variable memory: stack, bitwise AND, zero included",
31         .insns = {
32         /* set max stack size */
33         BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
34         /* set r3 to a random value */
35         BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
36         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
37         /* use bitwise AND to limit r3 range to [0, 64] */
38         BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 64),
39         BPF_LD_MAP_FD(BPF_REG_1, 0),
40         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
41         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
42         BPF_MOV64_IMM(BPF_REG_4, 0),
43         /* Call bpf_ringbuf_output(), it is one of a few helper functions with
44          * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
45          * For unpriv this should signal an error, because memory at &fp[-64] is
46          * not initialized.
47          */
48         BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
49         BPF_EXIT_INSN(),
50         },
51         .fixup_map_ringbuf = { 4 },
52         .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64",
53         .result_unpriv = REJECT,
54         /* in privileged mode reads from uninitialized stack locations are permitted */
55         .result = ACCEPT,
56 },
57 {
58         "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
59         .insns = {
60         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
61         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
62         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
63         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
64         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
65         BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
66         BPF_MOV64_IMM(BPF_REG_4, 0),
67         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
68         BPF_MOV64_IMM(BPF_REG_3, 0),
69         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
70         BPF_MOV64_IMM(BPF_REG_0, 0),
71         BPF_EXIT_INSN(),
72         },
73         .errstr = "invalid indirect access to stack R1 off=-64 size=65",
74         .result = REJECT,
75         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
76 },
77 {
78         "helper access to variable memory: stack, JMP, correct bounds",
79         .insns = {
80         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
81         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
82         BPF_MOV64_IMM(BPF_REG_0, 0),
83         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
84         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
85         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
86         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
87         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
88         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
89         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
90         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
91         BPF_MOV64_IMM(BPF_REG_2, 16),
92         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
93         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
94         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
95         BPF_MOV64_IMM(BPF_REG_4, 0),
96         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
97         BPF_MOV64_IMM(BPF_REG_3, 0),
98         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
99         BPF_MOV64_IMM(BPF_REG_0, 0),
100         BPF_EXIT_INSN(),
101         },
102         .result = ACCEPT,
103         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
104 },
105 {
106         "helper access to variable memory: stack, JMP (signed), correct bounds",
107         .insns = {
108         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
109         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
110         BPF_MOV64_IMM(BPF_REG_0, 0),
111         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
112         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
113         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
114         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
115         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
116         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
117         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
118         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
119         BPF_MOV64_IMM(BPF_REG_2, 16),
120         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
121         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
122         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
123         BPF_MOV64_IMM(BPF_REG_4, 0),
124         BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
125         BPF_MOV64_IMM(BPF_REG_3, 0),
126         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
127         BPF_MOV64_IMM(BPF_REG_0, 0),
128         BPF_EXIT_INSN(),
129         },
130         .result = ACCEPT,
131         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
132 },
133 {
134         "helper access to variable memory: stack, JMP, bounds + offset",
135         .insns = {
136         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
137         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
138         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
139         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
140         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
141         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
142         BPF_MOV64_IMM(BPF_REG_4, 0),
143         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
144         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
145         BPF_MOV64_IMM(BPF_REG_3, 0),
146         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
147         BPF_MOV64_IMM(BPF_REG_0, 0),
148         BPF_EXIT_INSN(),
149         },
150         .errstr = "invalid indirect access to stack R1 off=-64 size=65",
151         .result = REJECT,
152         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
153 },
154 {
155         "helper access to variable memory: stack, JMP, wrong max",
156         .insns = {
157         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
158         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
159         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
160         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
161         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
162         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
163         BPF_MOV64_IMM(BPF_REG_4, 0),
164         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
165         BPF_MOV64_IMM(BPF_REG_3, 0),
166         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
167         BPF_MOV64_IMM(BPF_REG_0, 0),
168         BPF_EXIT_INSN(),
169         },
170         .errstr = "invalid indirect access to stack R1 off=-64 size=65",
171         .result = REJECT,
172         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
173 },
174 {
175         "helper access to variable memory: stack, JMP, no max check",
176         .insns = {
177         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
178         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
179         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
180         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
181         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
182         BPF_MOV64_IMM(BPF_REG_4, 0),
183         BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
184         BPF_MOV64_IMM(BPF_REG_3, 0),
185         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
186         BPF_MOV64_IMM(BPF_REG_0, 0),
187         BPF_EXIT_INSN(),
188         },
189         /* because max wasn't checked, signed min is negative */
190         .errstr = "R2 min value is negative, either use unsigned or 'var &= const'",
191         .result = REJECT,
192         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
193 },
194 {
195         "helper access to variable memory: stack, JMP, no min check",
196         .insns = {
197         /* set max stack size */
198         BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
199         /* set r3 to a random value */
200         BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
201         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
202         /* use JMP to limit r3 range to [0, 64] */
203         BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 64, 6),
204         BPF_LD_MAP_FD(BPF_REG_1, 0),
205         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
206         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
207         BPF_MOV64_IMM(BPF_REG_4, 0),
208         /* Call bpf_ringbuf_output(), it is one of a few helper functions with
209          * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
210          * For unpriv this should signal an error, because memory at &fp[-64] is
211          * not initialized.
212          */
213         BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
214         BPF_MOV64_IMM(BPF_REG_0, 0),
215         BPF_EXIT_INSN(),
216         },
217         .fixup_map_ringbuf = { 4 },
218         .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64",
219         .result_unpriv = REJECT,
220         /* in privileged mode reads from uninitialized stack locations are permitted */
221         .result = ACCEPT,
222 },
223 {
224         "helper access to variable memory: stack, JMP (signed), no min check",
225         .insns = {
226         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8),
227         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
228         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
229         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
230         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
231         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
232         BPF_MOV64_IMM(BPF_REG_3, 0),
233         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
234         BPF_MOV64_IMM(BPF_REG_0, 0),
235         BPF_EXIT_INSN(),
236         },
237         .errstr = "R2 min value is negative",
238         .result = REJECT,
239         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
240 },
241 {
242         "helper access to variable memory: map, JMP, correct bounds",
243         .insns = {
244         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
245         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
246         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
247         BPF_LD_MAP_FD(BPF_REG_1, 0),
248         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
249         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
250         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
251         BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
252         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
253         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
254         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, sizeof(struct test_val), 4),
255         BPF_MOV64_IMM(BPF_REG_4, 0),
256         BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
257         BPF_MOV64_IMM(BPF_REG_3, 0),
258         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
259         BPF_MOV64_IMM(BPF_REG_0, 0),
260         BPF_EXIT_INSN(),
261         },
262         .fixup_map_hash_48b = { 3 },
263         .result = ACCEPT,
264         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
265 },
266 {
267         "helper access to variable memory: map, JMP, wrong max",
268         .insns = {
269         BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
270         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
271         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
272         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
273         BPF_LD_MAP_FD(BPF_REG_1, 0),
274         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
275         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
276         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
277         BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
278         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
279         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
280         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, sizeof(struct test_val) + 1, 4),
281         BPF_MOV64_IMM(BPF_REG_4, 0),
282         BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
283         BPF_MOV64_IMM(BPF_REG_3, 0),
284         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
285         BPF_MOV64_IMM(BPF_REG_0, 0),
286         BPF_EXIT_INSN(),
287         },
288         .fixup_map_hash_48b = { 4 },
289         .errstr = "invalid access to map value, value_size=48 off=0 size=49",
290         .result = REJECT,
291         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
292 },
293 {
294         "helper access to variable memory: map adjusted, JMP, correct bounds",
295         .insns = {
296         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
297         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
298         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
299         BPF_LD_MAP_FD(BPF_REG_1, 0),
300         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
301         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
302         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
303         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
304         BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
305         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
306         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
307         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, sizeof(struct test_val) - 20, 4),
308         BPF_MOV64_IMM(BPF_REG_4, 0),
309         BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
310         BPF_MOV64_IMM(BPF_REG_3, 0),
311         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
312         BPF_MOV64_IMM(BPF_REG_0, 0),
313         BPF_EXIT_INSN(),
314         },
315         .fixup_map_hash_48b = { 3 },
316         .result = ACCEPT,
317         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
318 },
319 {
320         "helper access to variable memory: map adjusted, JMP, wrong max",
321         .insns = {
322         BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 8),
323         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
324         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
325         BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
326         BPF_LD_MAP_FD(BPF_REG_1, 0),
327         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
328         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
329         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
330         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
331         BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
332         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
333         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
334         BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, sizeof(struct test_val) - 19, 4),
335         BPF_MOV64_IMM(BPF_REG_4, 0),
336         BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
337         BPF_MOV64_IMM(BPF_REG_3, 0),
338         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
339         BPF_MOV64_IMM(BPF_REG_0, 0),
340         BPF_EXIT_INSN(),
341         },
342         .fixup_map_hash_48b = { 4 },
343         .errstr = "R1 min value is outside of the allowed memory range",
344         .result = REJECT,
345         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
346 },
347 {
348         "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
349         .insns = {
350         BPF_MOV64_IMM(BPF_REG_1, 0),
351         BPF_MOV64_IMM(BPF_REG_2, 0),
352         BPF_MOV64_IMM(BPF_REG_3, 0),
353         BPF_MOV64_IMM(BPF_REG_4, 0),
354         BPF_MOV64_IMM(BPF_REG_5, 0),
355         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
356         BPF_EXIT_INSN(),
357         },
358         .result = ACCEPT,
359         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
360 },
361 {
362         "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)",
363         .insns = {
364         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
365         BPF_MOV64_IMM(BPF_REG_1, 0),
366         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
367         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
368         BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
369         BPF_MOV64_IMM(BPF_REG_3, 0),
370         BPF_MOV64_IMM(BPF_REG_4, 0),
371         BPF_MOV64_IMM(BPF_REG_5, 0),
372         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
373         BPF_EXIT_INSN(),
374         },
375         .errstr = "R1 type=scalar expected=fp",
376         .result = REJECT,
377         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
378 },
379 {
380         "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
381         .insns = {
382         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
383         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
384         BPF_MOV64_IMM(BPF_REG_2, 0),
385         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
386         BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
387         BPF_MOV64_IMM(BPF_REG_3, 0),
388         BPF_MOV64_IMM(BPF_REG_4, 0),
389         BPF_MOV64_IMM(BPF_REG_5, 0),
390         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
391         BPF_EXIT_INSN(),
392         },
393         .result = ACCEPT,
394         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
395 },
396 {
397         "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
398         .insns = {
399         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
400         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
401         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
402         BPF_LD_MAP_FD(BPF_REG_1, 0),
403         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
404         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
405         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
406         BPF_MOV64_IMM(BPF_REG_2, 0),
407         BPF_MOV64_IMM(BPF_REG_3, 0),
408         BPF_MOV64_IMM(BPF_REG_4, 0),
409         BPF_MOV64_IMM(BPF_REG_5, 0),
410         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
411         BPF_EXIT_INSN(),
412         },
413         .fixup_map_hash_8b = { 3 },
414         .result = ACCEPT,
415         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
416 },
417 {
418         "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)",
419         .insns = {
420         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
421         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
422         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
423         BPF_LD_MAP_FD(BPF_REG_1, 0),
424         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
425         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
426         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
427         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 7),
428         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
429         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
430         BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
431         BPF_MOV64_IMM(BPF_REG_3, 0),
432         BPF_MOV64_IMM(BPF_REG_4, 0),
433         BPF_MOV64_IMM(BPF_REG_5, 0),
434         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
435         BPF_EXIT_INSN(),
436         },
437         .fixup_map_hash_8b = { 3 },
438         .result = ACCEPT,
439         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
440 },
441 {
442         "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)",
443         .insns = {
444         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
445         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
446         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
447         BPF_LD_MAP_FD(BPF_REG_1, 0),
448         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
449         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
450         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
451         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
452         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
453         BPF_MOV64_IMM(BPF_REG_3, 0),
454         BPF_MOV64_IMM(BPF_REG_4, 0),
455         BPF_MOV64_IMM(BPF_REG_5, 0),
456         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
457         BPF_EXIT_INSN(),
458         },
459         .fixup_map_hash_8b = { 3 },
460         .result = ACCEPT,
461         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
462 },
463 {
464         "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)",
465         .insns = {
466         BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
467                     offsetof(struct __sk_buff, data)),
468         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
469                     offsetof(struct __sk_buff, data_end)),
470         BPF_MOV64_REG(BPF_REG_0, BPF_REG_6),
471         BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8),
472         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
473         BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
474         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_6, 0),
475         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
476         BPF_MOV64_IMM(BPF_REG_3, 0),
477         BPF_MOV64_IMM(BPF_REG_4, 0),
478         BPF_MOV64_IMM(BPF_REG_5, 0),
479         BPF_EMIT_CALL(BPF_FUNC_csum_diff),
480         BPF_EXIT_INSN(),
481         },
482         .result = ACCEPT,
483         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
484         .retval = 0 /* csum_diff of 64-byte packet */,
485         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
486 },
487 {
488         "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
489         .insns = {
490         BPF_MOV64_IMM(BPF_REG_1, 0),
491         BPF_MOV64_IMM(BPF_REG_2, 0),
492         BPF_MOV64_IMM(BPF_REG_3, 0),
493         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
494         BPF_EXIT_INSN(),
495         },
496         .errstr = "R1 type=scalar expected=fp",
497         .result = REJECT,
498         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
499 },
500 {
501         "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
502         .insns = {
503         BPF_MOV64_IMM(BPF_REG_1, 0),
504         BPF_MOV64_IMM(BPF_REG_2, 1),
505         BPF_MOV64_IMM(BPF_REG_3, 0),
506         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
507         BPF_EXIT_INSN(),
508         },
509         .errstr = "R1 type=scalar expected=fp",
510         .result = REJECT,
511         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
512 },
513 {
514         "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
515         .insns = {
516         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
517         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
518         BPF_MOV64_IMM(BPF_REG_2, 0),
519         BPF_MOV64_IMM(BPF_REG_3, 0),
520         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
521         BPF_EXIT_INSN(),
522         },
523         .result = ACCEPT,
524         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
525 },
526 {
527         "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
528         .insns = {
529         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
530         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
531         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
532         BPF_LD_MAP_FD(BPF_REG_1, 0),
533         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
534         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
535         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
536         BPF_MOV64_IMM(BPF_REG_2, 0),
537         BPF_MOV64_IMM(BPF_REG_3, 0),
538         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
539         BPF_EXIT_INSN(),
540         },
541         .fixup_map_hash_8b = { 3 },
542         .result = ACCEPT,
543         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
544 },
545 {
546         "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)",
547         .insns = {
548         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
549         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
550         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
551         BPF_LD_MAP_FD(BPF_REG_1, 0),
552         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
553         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
554         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
555         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4),
556         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
557         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
558         BPF_MOV64_IMM(BPF_REG_3, 0),
559         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
560         BPF_EXIT_INSN(),
561         },
562         .fixup_map_hash_8b = { 3 },
563         .result = ACCEPT,
564         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
565 },
566 {
567         "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)",
568         .insns = {
569         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
570         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
571         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
572         BPF_LD_MAP_FD(BPF_REG_1, 0),
573         BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
574         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
575         BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
576         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
577         BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2),
578         BPF_MOV64_IMM(BPF_REG_3, 0),
579         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
580         BPF_EXIT_INSN(),
581         },
582         .fixup_map_hash_8b = { 3 },
583         .result = ACCEPT,
584         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
585 },
586 {
587         "helper access to variable memory: 8 bytes leak",
588         .insns = {
589         /* set max stack size */
590         BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0),
591         /* set r3 to a random value */
592         BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
593         BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
594         BPF_LD_MAP_FD(BPF_REG_1, 0),
595         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
596         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),
597         BPF_MOV64_IMM(BPF_REG_0, 0),
598         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
599         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
600         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
601         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
602         /* Note: fp[-32] left uninitialized */
603         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
604         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
605         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
606         /* Limit r3 range to [1, 64] */
607         BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 63),
608         BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 1),
609         BPF_MOV64_IMM(BPF_REG_4, 0),
610         /* Call bpf_ringbuf_output(), it is one of a few helper functions with
611          * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode.
612          * For unpriv this should signal an error, because memory region [1, 64]
613          * at &fp[-64] is not fully initialized.
614          */
615         BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),
616         BPF_MOV64_IMM(BPF_REG_0, 0),
617         BPF_EXIT_INSN(),
618         },
619         .fixup_map_ringbuf = { 3 },
620         .errstr_unpriv = "invalid indirect read from stack R2 off -64+32 size 64",
621         .result_unpriv = REJECT,
622         /* in privileged mode reads from uninitialized stack locations are permitted */
623         .result = ACCEPT,
624 },
625 {
626         "helper access to variable memory: 8 bytes no leak (init memory)",
627         .insns = {
628         BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
629         BPF_MOV64_IMM(BPF_REG_0, 0),
630         BPF_MOV64_IMM(BPF_REG_0, 0),
631         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
632         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
633         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
634         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
635         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
636         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
637         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
638         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
639         BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
640         BPF_MOV64_IMM(BPF_REG_2, 0),
641         BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
642         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
643         BPF_MOV64_IMM(BPF_REG_3, 0),
644         BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
645         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
646         BPF_EXIT_INSN(),
647         },
648         .result = ACCEPT,
649         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
650 },