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