Merge tag 'v5.18' into next
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / verifier / search_pruning.c
1 {
2         "pointer/scalar confusion in state equality check (way 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, 2),
10         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
11         BPF_JMP_A(1),
12         BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
13         BPF_JMP_A(0),
14         BPF_EXIT_INSN(),
15         },
16         .fixup_map_hash_8b = { 3 },
17         .result = ACCEPT,
18         .retval = POINTER_VALUE,
19         .result_unpriv = REJECT,
20         .errstr_unpriv = "R0 leaks addr as return value"
21 },
22 {
23         "pointer/scalar confusion in state equality check (way 2)",
24         .insns = {
25         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
26         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
27         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
28         BPF_LD_MAP_FD(BPF_REG_1, 0),
29         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
30         BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
31         BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
32         BPF_JMP_A(1),
33         BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
34         BPF_EXIT_INSN(),
35         },
36         .fixup_map_hash_8b = { 3 },
37         .result = ACCEPT,
38         .retval = POINTER_VALUE,
39         .result_unpriv = REJECT,
40         .errstr_unpriv = "R0 leaks addr as return value"
41 },
42 {
43         "liveness pruning and write screening",
44         .insns = {
45         /* Get an unknown value */
46         BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
47         /* branch conditions teach us nothing about R2 */
48         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
49         BPF_MOV64_IMM(BPF_REG_0, 0),
50         BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
51         BPF_MOV64_IMM(BPF_REG_0, 0),
52         BPF_EXIT_INSN(),
53         },
54         .errstr = "R0 !read_ok",
55         .result = REJECT,
56         .prog_type = BPF_PROG_TYPE_LWT_IN,
57 },
58 {
59         "varlen_map_value_access pruning",
60         .insns = {
61         BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
62         BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
63         BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
64         BPF_LD_MAP_FD(BPF_REG_1, 0),
65         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
66         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
67         BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
68         BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
69         BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
70         BPF_MOV32_IMM(BPF_REG_1, 0),
71         BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
72         BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
73         BPF_JMP_IMM(BPF_JA, 0, 0, 0),
74         BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
75         BPF_EXIT_INSN(),
76         },
77         .fixup_map_hash_48b = { 3 },
78         .errstr_unpriv = "R0 leaks addr",
79         .errstr = "R0 unbounded memory access",
80         .result_unpriv = REJECT,
81         .result = REJECT,
82         .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
83 },
84 {
85         "search pruning: all branches should be verified (nop operation)",
86         .insns = {
87                 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
88                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
89                 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
90                 BPF_LD_MAP_FD(BPF_REG_1, 0),
91                 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
92                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
93                 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
94                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
95                 BPF_MOV64_IMM(BPF_REG_4, 0),
96                 BPF_JMP_A(1),
97                 BPF_MOV64_IMM(BPF_REG_4, 1),
98                 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
99                 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
100                 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
101                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
102                 BPF_MOV64_IMM(BPF_REG_6, 0),
103                 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
104                 BPF_EXIT_INSN(),
105         },
106         .fixup_map_hash_8b = { 3 },
107         .errstr = "R6 invalid mem access 'scalar'",
108         .result = REJECT,
109         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
110 },
111 {
112         "search pruning: all branches should be verified (invalid stack access)",
113         .insns = {
114                 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
115                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
116                 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
117                 BPF_LD_MAP_FD(BPF_REG_1, 0),
118                 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
119                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
120                 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
121                 BPF_MOV64_IMM(BPF_REG_4, 0),
122                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
123                 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
124                 BPF_JMP_A(1),
125                 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
126                 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
127                 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
128                 BPF_EXIT_INSN(),
129         },
130         .fixup_map_hash_8b = { 3 },
131         .errstr = "invalid read from stack off -16+0 size 8",
132         .result = REJECT,
133         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
134 },
135 {
136         "precision tracking for u32 spill/fill",
137         .insns = {
138                 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
139                 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
140                 BPF_MOV32_IMM(BPF_REG_6, 32),
141                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
142                 BPF_MOV32_IMM(BPF_REG_6, 4),
143                 /* Additional insns to introduce a pruning point. */
144                 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
145                 BPF_MOV64_IMM(BPF_REG_3, 0),
146                 BPF_MOV64_IMM(BPF_REG_3, 0),
147                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
148                 BPF_MOV64_IMM(BPF_REG_3, 0),
149                 /* u32 spill/fill */
150                 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -8),
151                 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_10, -8),
152                 /* out-of-bound map value access for r6=32 */
153                 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
154                 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
155                 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
156                 BPF_LD_MAP_FD(BPF_REG_1, 0),
157                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
158                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
159                 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
160                 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
161                 BPF_MOV64_IMM(BPF_REG_0, 0),
162                 BPF_EXIT_INSN(),
163         },
164         .fixup_map_hash_8b = { 15 },
165         .result = REJECT,
166         .errstr = "R0 min value is outside of the allowed memory range",
167         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
168 },
169 {
170         "precision tracking for u32 spills, u64 fill",
171         .insns = {
172                 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
173                 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
174                 BPF_MOV32_IMM(BPF_REG_7, 0xffffffff),
175                 /* Additional insns to introduce a pruning point. */
176                 BPF_MOV64_IMM(BPF_REG_3, 1),
177                 BPF_MOV64_IMM(BPF_REG_3, 1),
178                 BPF_MOV64_IMM(BPF_REG_3, 1),
179                 BPF_MOV64_IMM(BPF_REG_3, 1),
180                 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
181                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
182                 BPF_MOV64_IMM(BPF_REG_3, 1),
183                 BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
184                 /* u32 spills, u64 fill */
185                 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
186                 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
187                 BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, -8),
188                 /* if r8 != X goto pc+1  r8 known in fallthrough branch */
189                 BPF_JMP_IMM(BPF_JNE, BPF_REG_8, 0xffffffff, 1),
190                 BPF_MOV64_IMM(BPF_REG_3, 1),
191                 /* if r8 == X goto pc+1  condition always true on first
192                  * traversal, so starts backtracking to mark r8 as requiring
193                  * precision. r7 marked as needing precision. r6 not marked
194                  * since it's not tracked.
195                  */
196                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 0xffffffff, 1),
197                 /* fails if r8 correctly marked unknown after fill. */
198                 BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
199                 BPF_MOV64_IMM(BPF_REG_0, 0),
200                 BPF_EXIT_INSN(),
201         },
202         .result = REJECT,
203         .errstr = "div by zero",
204         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
205 },
206 {
207         "allocated_stack",
208         .insns = {
209                 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
210                 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
211                 BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
212                 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
213                 BPF_MOV64_IMM(BPF_REG_0, 0),
214                 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
215                 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, -8),
216                 BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_7, -9),
217                 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_10, -9),
218                 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
219                 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
220                 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
221                 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
222                 BPF_EXIT_INSN(),
223         },
224         .result = ACCEPT,
225         .result_unpriv = ACCEPT,
226         .insn_processed = 15,
227 },