WIP FPC-III support
[linux/fpc-iii.git] / tools / testing / selftests / bpf / verifier / var_off.c
blob8504ac9378098962be2d7bbec6f04e0907e5699d
2 "variable-offset ctx access",
3 .insns = {
4 /* Get an unknown value */
5 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
6 /* Make it small and 4-byte aligned */
7 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
8 /* add it to skb. We now have either &skb->len or
9 * &skb->pkt_type, but we don't know which
11 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
12 /* dereference it */
13 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
14 BPF_EXIT_INSN(),
16 .errstr = "variable ctx access var_off=(0x0; 0x4)",
17 .result = REJECT,
18 .prog_type = BPF_PROG_TYPE_LWT_IN,
21 "variable-offset stack access",
22 .insns = {
23 /* Fill the top 8 bytes of the stack */
24 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
25 /* Get an unknown value */
26 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
27 /* Make it small and 4-byte aligned */
28 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
29 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
30 /* add it to fp. We now have either fp-4 or fp-8, but
31 * we don't know which
33 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
34 /* dereference it */
35 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
36 BPF_EXIT_INSN(),
38 .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
39 .result = REJECT,
40 .prog_type = BPF_PROG_TYPE_LWT_IN,
43 "indirect variable-offset stack access, unbounded",
44 .insns = {
45 BPF_MOV64_IMM(BPF_REG_2, 6),
46 BPF_MOV64_IMM(BPF_REG_3, 28),
47 /* Fill the top 16 bytes of the stack. */
48 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
49 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
50 /* Get an unknown value. */
51 BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, offsetof(struct bpf_sock_ops,
52 bytes_received)),
53 /* Check the lower bound but don't check the upper one. */
54 BPF_JMP_IMM(BPF_JSLT, BPF_REG_4, 0, 4),
55 /* Point the lower bound to initialized stack. Offset is now in range
56 * from fp-16 to fp+0x7fffffffffffffef, i.e. max value is unbounded.
58 BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16),
59 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10),
60 BPF_MOV64_IMM(BPF_REG_5, 8),
61 /* Dereference it indirectly. */
62 BPF_EMIT_CALL(BPF_FUNC_getsockopt),
63 BPF_MOV64_IMM(BPF_REG_0, 0),
64 BPF_EXIT_INSN(),
66 .errstr = "R4 unbounded indirect variable offset stack access",
67 .result = REJECT,
68 .prog_type = BPF_PROG_TYPE_SOCK_OPS,
71 "indirect variable-offset stack access, max out of bound",
72 .insns = {
73 /* Fill the top 8 bytes of the stack */
74 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
75 /* Get an unknown value */
76 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
77 /* Make it small and 4-byte aligned */
78 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
79 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
80 /* add it to fp. We now have either fp-4 or fp-8, but
81 * we don't know which
83 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
84 /* dereference it indirectly */
85 BPF_LD_MAP_FD(BPF_REG_1, 0),
86 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
87 BPF_MOV64_IMM(BPF_REG_0, 0),
88 BPF_EXIT_INSN(),
90 .fixup_map_hash_8b = { 5 },
91 .errstr = "R2 max value is outside of stack bound",
92 .result = REJECT,
93 .prog_type = BPF_PROG_TYPE_LWT_IN,
96 "indirect variable-offset stack access, min out of bound",
97 .insns = {
98 /* Fill the top 8 bytes of the stack */
99 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
100 /* Get an unknown value */
101 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
102 /* Make it small and 4-byte aligned */
103 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
104 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 516),
105 /* add it to fp. We now have either fp-516 or fp-512, but
106 * we don't know which
108 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
109 /* dereference it indirectly */
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_MOV64_IMM(BPF_REG_0, 0),
113 BPF_EXIT_INSN(),
115 .fixup_map_hash_8b = { 5 },
116 .errstr = "R2 min value is outside of stack bound",
117 .result = REJECT,
118 .prog_type = BPF_PROG_TYPE_LWT_IN,
121 "indirect variable-offset stack access, max_off+size > max_initialized",
122 .insns = {
123 /* Fill only the second from top 8 bytes of the stack. */
124 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
125 /* Get an unknown value. */
126 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
127 /* Make it small and 4-byte aligned. */
128 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
129 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
130 /* Add it to fp. We now have either fp-12 or fp-16, but we don't know
131 * which. fp-12 size 8 is partially uninitialized stack.
133 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
134 /* Dereference it indirectly. */
135 BPF_LD_MAP_FD(BPF_REG_1, 0),
136 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
137 BPF_MOV64_IMM(BPF_REG_0, 0),
138 BPF_EXIT_INSN(),
140 .fixup_map_hash_8b = { 5 },
141 .errstr = "invalid indirect read from stack var_off",
142 .result = REJECT,
143 .prog_type = BPF_PROG_TYPE_LWT_IN,
146 "indirect variable-offset stack access, min_off < min_initialized",
147 .insns = {
148 /* Fill only the top 8 bytes of the stack. */
149 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
150 /* Get an unknown value */
151 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
152 /* Make it small and 4-byte aligned. */
153 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
154 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
155 /* Add it to fp. We now have either fp-12 or fp-16, but we don't know
156 * which. fp-16 size 8 is partially uninitialized stack.
158 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
159 /* Dereference it indirectly. */
160 BPF_LD_MAP_FD(BPF_REG_1, 0),
161 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
162 BPF_MOV64_IMM(BPF_REG_0, 0),
163 BPF_EXIT_INSN(),
165 .fixup_map_hash_8b = { 5 },
166 .errstr = "invalid indirect read from stack var_off",
167 .result = REJECT,
168 .prog_type = BPF_PROG_TYPE_LWT_IN,
171 "indirect variable-offset stack access, priv vs unpriv",
172 .insns = {
173 /* Fill the top 16 bytes of the stack. */
174 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
175 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
176 /* Get an unknown value. */
177 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
178 /* Make it small and 4-byte aligned. */
179 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
180 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
181 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
182 * which, but either way it points to initialized stack.
184 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
185 /* Dereference it indirectly. */
186 BPF_LD_MAP_FD(BPF_REG_1, 0),
187 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
188 BPF_MOV64_IMM(BPF_REG_0, 0),
189 BPF_EXIT_INSN(),
191 .fixup_map_hash_8b = { 6 },
192 .errstr_unpriv = "R2 stack pointer arithmetic goes out of range, prohibited for !root",
193 .result_unpriv = REJECT,
194 .result = ACCEPT,
195 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
198 "indirect variable-offset stack access, uninitialized",
199 .insns = {
200 BPF_MOV64_IMM(BPF_REG_2, 6),
201 BPF_MOV64_IMM(BPF_REG_3, 28),
202 /* Fill the top 16 bytes of the stack. */
203 BPF_ST_MEM(BPF_W, BPF_REG_10, -16, 0),
204 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
205 /* Get an unknown value. */
206 BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 0),
207 /* Make it small and 4-byte aligned. */
208 BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 4),
209 BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16),
210 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
211 * which, but either way it points to initialized stack.
213 BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10),
214 BPF_MOV64_IMM(BPF_REG_5, 8),
215 /* Dereference it indirectly. */
216 BPF_EMIT_CALL(BPF_FUNC_getsockopt),
217 BPF_MOV64_IMM(BPF_REG_0, 0),
218 BPF_EXIT_INSN(),
220 .errstr = "invalid indirect read from stack var_off",
221 .result = REJECT,
222 .prog_type = BPF_PROG_TYPE_SOCK_OPS,
225 "indirect variable-offset stack access, ok",
226 .insns = {
227 /* Fill the top 16 bytes of the stack. */
228 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
229 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
230 /* Get an unknown value. */
231 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
232 /* Make it small and 4-byte aligned. */
233 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
234 BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
235 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
236 * which, but either way it points to initialized stack.
238 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
239 /* Dereference it indirectly. */
240 BPF_LD_MAP_FD(BPF_REG_1, 0),
241 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
242 BPF_MOV64_IMM(BPF_REG_0, 0),
243 BPF_EXIT_INSN(),
245 .fixup_map_hash_8b = { 6 },
246 .result = ACCEPT,
247 .prog_type = BPF_PROG_TYPE_LWT_IN,