Merge tag 'usb-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux-block.git] / tools / testing / selftests / bpf / verifier / spill_fill.c
1 {
2         "check valid spill/fill",
3         .insns = {
4         /* spill R1(ctx) into stack */
5         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
6         /* fill it back into R2 */
7         BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
8         /* should be able to access R0 = *(R2 + 8) */
9         /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
10         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
11         BPF_EXIT_INSN(),
12         },
13         .errstr_unpriv = "R0 leaks addr",
14         .result = ACCEPT,
15         .result_unpriv = REJECT,
16         .retval = POINTER_VALUE,
17 },
18 {
19         "check valid spill/fill, skb mark",
20         .insns = {
21         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
22         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
23         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
24         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
25                     offsetof(struct __sk_buff, mark)),
26         BPF_EXIT_INSN(),
27         },
28         .result = ACCEPT,
29         .result_unpriv = ACCEPT,
30 },
31 {
32         "check valid spill/fill, ptr to mem",
33         .insns = {
34         /* reserve 8 byte ringbuf memory */
35         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
36         BPF_LD_MAP_FD(BPF_REG_1, 0),
37         BPF_MOV64_IMM(BPF_REG_2, 8),
38         BPF_MOV64_IMM(BPF_REG_3, 0),
39         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
40         /* store a pointer to the reserved memory in R6 */
41         BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
42         /* check whether the reservation was successful */
43         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
44         /* spill R6(mem) into the stack */
45         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
46         /* fill it back in R7 */
47         BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8),
48         /* should be able to access *(R7) = 0 */
49         BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0),
50         /* submit the reserved ringbuf memory */
51         BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
52         BPF_MOV64_IMM(BPF_REG_2, 0),
53         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
54         BPF_MOV64_IMM(BPF_REG_0, 0),
55         BPF_EXIT_INSN(),
56         },
57         .fixup_map_ringbuf = { 1 },
58         .result = ACCEPT,
59         .result_unpriv = ACCEPT,
60 },
61 {
62         "check corrupted spill/fill",
63         .insns = {
64         /* spill R1(ctx) into stack */
65         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
66         /* mess up with R1 pointer on stack */
67         BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
68         /* fill back into R0 is fine for priv.
69          * R0 now becomes SCALAR_VALUE.
70          */
71         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
72         /* Load from R0 should fail. */
73         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
74         BPF_EXIT_INSN(),
75         },
76         .errstr_unpriv = "attempt to corrupt spilled",
77         .errstr = "R0 invalid mem access 'inv",
78         .result = REJECT,
79         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
80 },
81 {
82         "check corrupted spill/fill, LSB",
83         .insns = {
84         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
85         BPF_ST_MEM(BPF_H, BPF_REG_10, -8, 0xcafe),
86         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
87         BPF_EXIT_INSN(),
88         },
89         .errstr_unpriv = "attempt to corrupt spilled",
90         .result_unpriv = REJECT,
91         .result = ACCEPT,
92         .retval = POINTER_VALUE,
93 },
94 {
95         "check corrupted spill/fill, MSB",
96         .insns = {
97         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
98         BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0x12345678),
99         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
100         BPF_EXIT_INSN(),
101         },
102         .errstr_unpriv = "attempt to corrupt spilled",
103         .result_unpriv = REJECT,
104         .result = ACCEPT,
105         .retval = POINTER_VALUE,
106 },
107 {
108         "Spill and refill a u32 const scalar.  Offset to skb->data",
109         .insns = {
110         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
111                     offsetof(struct __sk_buff, data)),
112         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
113                     offsetof(struct __sk_buff, data_end)),
114         /* r4 = 20 */
115         BPF_MOV32_IMM(BPF_REG_4, 20),
116         /* *(u32 *)(r10 -8) = r4 */
117         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
118         /* r4 = *(u32 *)(r10 -8) */
119         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -8),
120         /* r0 = r2 */
121         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
122         /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv20 */
123         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
124         /* if (r0 > r3) R0=pkt,off=20 R2=pkt R3=pkt_end R4=inv20 */
125         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
126         /* r0 = *(u32 *)r2 R0=pkt,off=20,r=20 R2=pkt,r=20 R3=pkt_end R4=inv20 */
127         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
128         BPF_MOV64_IMM(BPF_REG_0, 0),
129         BPF_EXIT_INSN(),
130         },
131         .result = ACCEPT,
132         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
133 },
134 {
135         "Spill a u32 const, refill from another half of the uninit u32 from the stack",
136         .insns = {
137         /* r4 = 20 */
138         BPF_MOV32_IMM(BPF_REG_4, 20),
139         /* *(u32 *)(r10 -8) = r4 */
140         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
141         /* r4 = *(u32 *)(r10 -4) fp-8=????rrrr*/
142         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -4),
143         BPF_MOV64_IMM(BPF_REG_0, 0),
144         BPF_EXIT_INSN(),
145         },
146         .result = REJECT,
147         .errstr = "invalid read from stack off -4+0 size 4",
148         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
149 },
150 {
151         "Spill a u32 const scalar.  Refill as u16.  Offset to skb->data",
152         .insns = {
153         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
154                     offsetof(struct __sk_buff, data)),
155         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
156                     offsetof(struct __sk_buff, data_end)),
157         /* r4 = 20 */
158         BPF_MOV32_IMM(BPF_REG_4, 20),
159         /* *(u32 *)(r10 -8) = r4 */
160         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
161         /* r4 = *(u16 *)(r10 -8) */
162         BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
163         /* r0 = r2 */
164         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
165         /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=65535 */
166         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
167         /* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv,umax=65535 */
168         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
169         /* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv20 */
170         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
171         BPF_MOV64_IMM(BPF_REG_0, 0),
172         BPF_EXIT_INSN(),
173         },
174         .result = REJECT,
175         .errstr = "invalid access to packet",
176         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
177 },
178 {
179         "Spill u32 const scalars.  Refill as u64.  Offset to skb->data",
180         .insns = {
181         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
182                     offsetof(struct __sk_buff, data)),
183         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
184                     offsetof(struct __sk_buff, data_end)),
185         /* r6 = 0 */
186         BPF_MOV32_IMM(BPF_REG_6, 0),
187         /* r7 = 20 */
188         BPF_MOV32_IMM(BPF_REG_7, 20),
189         /* *(u32 *)(r10 -4) = r6 */
190         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
191         /* *(u32 *)(r10 -8) = r7 */
192         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
193         /* r4 = *(u64 *)(r10 -8) */
194         BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
195         /* r0 = r2 */
196         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
197         /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=65535 */
198         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
199         /* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv,umax=65535 */
200         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
201         /* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv20 */
202         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
203         BPF_MOV64_IMM(BPF_REG_0, 0),
204         BPF_EXIT_INSN(),
205         },
206         .result = REJECT,
207         .errstr = "invalid access to packet",
208         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
209 },
210 {
211         "Spill a u32 const scalar.  Refill as u16 from fp-6.  Offset to skb->data",
212         .insns = {
213         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
214                     offsetof(struct __sk_buff, data)),
215         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
216                     offsetof(struct __sk_buff, data_end)),
217         /* r4 = 20 */
218         BPF_MOV32_IMM(BPF_REG_4, 20),
219         /* *(u32 *)(r10 -8) = r4 */
220         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
221         /* r4 = *(u16 *)(r10 -6) */
222         BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -6),
223         /* r0 = r2 */
224         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
225         /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=65535 */
226         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
227         /* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv,umax=65535 */
228         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
229         /* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=inv20 */
230         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
231         BPF_MOV64_IMM(BPF_REG_0, 0),
232         BPF_EXIT_INSN(),
233         },
234         .result = REJECT,
235         .errstr = "invalid access to packet",
236         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
237 },
238 {
239         "Spill and refill a u32 const scalar at non 8byte aligned stack addr.  Offset to skb->data",
240         .insns = {
241         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
242                     offsetof(struct __sk_buff, data)),
243         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
244                     offsetof(struct __sk_buff, data_end)),
245         /* r4 = 20 */
246         BPF_MOV32_IMM(BPF_REG_4, 20),
247         /* *(u32 *)(r10 -8) = r4 */
248         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
249         /* *(u32 *)(r10 -4) = r4 */
250         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -4),
251         /* r4 = *(u32 *)(r10 -4),  */
252         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -4),
253         /* r0 = r2 */
254         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
255         /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=inv,umax=U32_MAX */
256         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
257         /* if (r0 > r3) R0=pkt,umax=U32_MAX R2=pkt R3=pkt_end R4=inv */
258         BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
259         /* r0 = *(u32 *)r2 R0=pkt,umax=U32_MAX R2=pkt R3=pkt_end R4=inv */
260         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
261         BPF_MOV64_IMM(BPF_REG_0, 0),
262         BPF_EXIT_INSN(),
263         },
264         .result = REJECT,
265         .errstr = "invalid access to packet",
266         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
267 },
268 {
269         "Spill and refill a umax=40 bounded scalar.  Offset to skb->data",
270         .insns = {
271         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
272                     offsetof(struct __sk_buff, data)),
273         BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
274                     offsetof(struct __sk_buff, data_end)),
275         BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1,
276                     offsetof(struct __sk_buff, tstamp)),
277         BPF_JMP_IMM(BPF_JLE, BPF_REG_4, 40, 2),
278         BPF_MOV64_IMM(BPF_REG_0, 0),
279         BPF_EXIT_INSN(),
280         /* *(u32 *)(r10 -8) = r4 R4=inv,umax=40 */
281         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
282         /* r4 = (*u32 *)(r10 - 8) */
283         BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -8),
284         /* r2 += r4 R2=pkt R4=inv,umax=40 */
285         BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_4),
286         /* r0 = r2 R2=pkt,umax=40 R4=inv,umax=40 */
287         BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
288         /* r2 += 20 R0=pkt,umax=40 R2=pkt,umax=40 */
289         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 20),
290         /* if (r2 > r3) R0=pkt,umax=40 R2=pkt,off=20,umax=40 */
291         BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_3, 1),
292         /* r0 = *(u32 *)r0 R0=pkt,r=20,umax=40 R2=pkt,off=20,r=20,umax=40 */
293         BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
294         BPF_MOV64_IMM(BPF_REG_0, 0),
295         BPF_EXIT_INSN(),
296         },
297         .result = ACCEPT,
298         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
299 },
300 {
301         "Spill a u32 scalar at fp-4 and then at fp-8",
302         .insns = {
303         /* r4 = 4321 */
304         BPF_MOV32_IMM(BPF_REG_4, 4321),
305         /* *(u32 *)(r10 -4) = r4 */
306         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -4),
307         /* *(u32 *)(r10 -8) = r4 */
308         BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
309         /* r4 = *(u64 *)(r10 -8) */
310         BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
311         BPF_MOV64_IMM(BPF_REG_0, 0),
312         BPF_EXIT_INSN(),
313         },
314         .result = ACCEPT,
315         .prog_type = BPF_PROG_TYPE_SCHED_CLS,
316 },