• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
254 	BPF_EXIT_INSN(),
255 	},
256 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
257 	.fixup_map_array_ro = { 3 },
258 	.result = ACCEPT,
259 	.retval = 65507,
260 },
261 {
262 	"invalid write map access into a read-only array 1",
263 	.insns = {
264 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
265 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
266 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
267 	BPF_LD_MAP_FD(BPF_REG_1, 0),
268 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
269 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
270 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
271 	BPF_EXIT_INSN(),
272 	},
273 	.fixup_map_array_ro = { 3 },
274 	.result = REJECT,
275 	.errstr = "write into map forbidden",
276 },
277 {
278 	"invalid write map access into a read-only array 2",
279 	.insns = {
280 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
281 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
282 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
283 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
284 	BPF_LD_MAP_FD(BPF_REG_1, 0),
285 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
286 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
287 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
288 	BPF_MOV64_IMM(BPF_REG_2, 0),
289 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
290 	BPF_MOV64_IMM(BPF_REG_4, 8),
291 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
292 		     BPF_FUNC_skb_load_bytes),
293 	BPF_EXIT_INSN(),
294 	},
295 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
296 	.fixup_map_array_ro = { 4 },
297 	.result = REJECT,
298 	.errstr = "write into map forbidden",
299 },
300 {
301 	"valid write map access into a write-only array 1",
302 	.insns = {
303 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
304 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
305 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
306 	BPF_LD_MAP_FD(BPF_REG_1, 0),
307 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
308 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
309 	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
310 	BPF_MOV64_IMM(BPF_REG_0, 1),
311 	BPF_EXIT_INSN(),
312 	},
313 	.fixup_map_array_wo = { 3 },
314 	.result = ACCEPT,
315 	.retval = 1,
316 },
317 {
318 	"valid write map access into a write-only array 2",
319 	.insns = {
320 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
321 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
322 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
323 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
324 	BPF_LD_MAP_FD(BPF_REG_1, 0),
325 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
326 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
327 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
328 	BPF_MOV64_IMM(BPF_REG_2, 0),
329 	BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
330 	BPF_MOV64_IMM(BPF_REG_4, 8),
331 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
332 		     BPF_FUNC_skb_load_bytes),
333 	BPF_EXIT_INSN(),
334 	},
335 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
336 	.fixup_map_array_wo = { 4 },
337 	.result = ACCEPT,
338 	.retval = 0,
339 },
340 {
341 	"invalid read map access into a write-only array 1",
342 	.insns = {
343 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
344 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
345 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
346 	BPF_LD_MAP_FD(BPF_REG_1, 0),
347 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
348 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
349 	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
350 	BPF_EXIT_INSN(),
351 	},
352 	.fixup_map_array_wo = { 3 },
353 	.result = REJECT,
354 	.errstr = "read from map forbidden",
355 },
356 {
357 	"invalid read map access into a write-only array 2",
358 	.insns = {
359 	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
360 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
361 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
362 	BPF_LD_MAP_FD(BPF_REG_1, 0),
363 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
364 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
365 
366 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
367 	BPF_MOV64_IMM(BPF_REG_2, 4),
368 	BPF_MOV64_IMM(BPF_REG_3, 0),
369 	BPF_MOV64_IMM(BPF_REG_4, 0),
370 	BPF_MOV64_IMM(BPF_REG_5, 0),
371 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
372 		     BPF_FUNC_csum_diff),
373 	BPF_EXIT_INSN(),
374 	},
375 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
376 	.fixup_map_array_wo = { 3 },
377 	.result = REJECT,
378 	.errstr = "read from map forbidden",
379 },
380