History

bpf, selftest: test {rd, wr}only flags and direct value access

Extend test_verifier with various test cases around the two kernel extensions, that is, {rd,wr}only map support as well as direct map value access. All passing, one skipped due to xskmap not present on test machine: # ./test_verifier [...] #948/p XDP pkt read, pkt_meta' <= pkt_data, bad access 1 OK #949/p XDP pkt read, pkt_meta' <= pkt_data, bad access 2 OK #950/p XDP pkt read, pkt_data <= pkt_meta', good access OK #951/p XDP pkt read, pkt_data <= pkt_meta', bad access 1 OK #952/p XDP pkt read, pkt_data <= pkt_meta', bad access 2 OK Summary: 1410 PASSED, 1 SKIPPED, 0 FAILED

Daniel Borkmann committed 7 years ago

Commit fb2abb71 parent 817998a4 files · +573 −5Browse files

Unified · Split

4 files
  1. tools/include/linux/filter.h +20 −1
  2. tools/testing/selftests/bpf/test_verifier.c +47 −4
  3. tools/testing/selftests/bpf/verifier/array_access.c +159 −0
  4. tools/testing/selftests/bpf/verifier/direct_value_access.c +347 −0
tools/include/linux/filter.h+20−1
@@ -278,10 +278,29 @@ · 277 unmodified lines
278278 .off = 0, \
279279 .imm = ((__u64) (IMM)) >> 32 })
280280
281+#define BPF_LD_IMM64_RAW_FULL(DST, SRC, OFF1, OFF2, IMM1, IMM2) \
282+ ((struct bpf_insn) { \
283+ .code = BPF_LD | BPF_DW | BPF_IMM, \
284+ .dst_reg = DST, \
285+ .src_reg = SRC, \
286+ .off = OFF1, \
287+ .imm = IMM1 }), \
288+ ((struct bpf_insn) { \
289+ .code = 0, /* zero is reserved opcode */ \
290+ .dst_reg = 0, \
291+ .src_reg = 0, \
292+ .off = OFF2, \
293+ .imm = IMM2 })
294+
281295 /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
282296
283297 #define BPF_LD_MAP_FD(DST, MAP_FD) \
284− BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
298+ BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_FD, 0, 0, \
299+ MAP_FD, 0)
300+
301+#define BPF_LD_MAP_VALUE(DST, MAP_FD, VALUE_OFF) \
302+ BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_VALUE, 0, 0, \
303+ MAP_FD, VALUE_OFF)
285304
286305 /* Relative call */
287306
tools/testing/selftests/bpf/test_verifier.c+47−4
@@ -52,7 +52,7 @@ · 51 unmodified lines
5252 #define MAX_INSNS BPF_MAXINSNS
5353 #define MAX_TEST_INSNS 1000000
5454 #define MAX_FIXUPS 8
55−#define MAX_NR_MAPS 14
55+#define MAX_NR_MAPS 16
5656 #define MAX_TEST_RUNS 8
5757 #define POINTER_VALUE 0xcafe4all
5858 #define TEST_DATA_LEN 64
@@ -82,6 +82,9 @@ struct bpf_test { · 23 unmodified lines
8282 int fixup_cgroup_storage[MAX_FIXUPS];
8383 int fixup_percpu_cgroup_storage[MAX_FIXUPS];
8484 int fixup_map_spin_lock[MAX_FIXUPS];
85+ int fixup_map_array_ro[MAX_FIXUPS];
86+ int fixup_map_array_wo[MAX_FIXUPS];
87+ int fixup_map_array_small[MAX_FIXUPS];
8588 const char *errstr;
8689 const char *errstr_unpriv;
8790 uint32_t retval, retval_unpriv, insn_processed;
@@ -285,13 +288,15 @@ static bool skip_unsupported_map(enum bpf_map_type map_type) · 197 unmodified lines
285288 return false;
286289 }
287290
288−static int create_map(uint32_t type, uint32_t size_key,
289− uint32_t size_value, uint32_t max_elem)
291+static int __create_map(uint32_t type, uint32_t size_key,
292+ uint32_t size_value, uint32_t max_elem,
293+ uint32_t extra_flags)
290294 {
291295 int fd;
292296
293297 fd = bpf_create_map(type, size_key, size_value, max_elem,
294− type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0);
298+ (type == BPF_MAP_TYPE_HASH ?
299+ BPF_F_NO_PREALLOC : 0) | extra_flags);
295300 if (fd < 0) {
296301 if (skip_unsupported_map(type))
297302 return -1;
@@ -301,6 +306,12 @@ static int create_map(uint32_t type, uint32_t size_key, · 3 unmodified lines
301306 return fd;
302307 }
303308
309+static int create_map(uint32_t type, uint32_t size_key,
310+ uint32_t size_value, uint32_t max_elem)
311+{
312+ return __create_map(type, size_key, size_value, max_elem, 0);
313+}
314+
304315 static void update_map(int fd, int index)
305316 {
306317 struct test_val value = {
@@ -527,6 +538,9 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, · 220 unmodified lines
527538 int *fixup_cgroup_storage = test->fixup_cgroup_storage;
528539 int *fixup_percpu_cgroup_storage = test->fixup_percpu_cgroup_storage;
529540 int *fixup_map_spin_lock = test->fixup_map_spin_lock;
541+ int *fixup_map_array_ro = test->fixup_map_array_ro;
542+ int *fixup_map_array_wo = test->fixup_map_array_wo;
543+ int *fixup_map_array_small = test->fixup_map_array_small;
530544
531545 if (test->fill_helper) {
532546 test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn));
@@ -652,6 +666,35 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, · 119 unmodified lines
652666 fixup_map_spin_lock++;
653667 } while (*fixup_map_spin_lock);
654668 }
669+ if (*fixup_map_array_ro) {
670+ map_fds[14] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
671+ sizeof(struct test_val), 1,
672+ BPF_F_RDONLY_PROG);
673+ update_map(map_fds[14], 0);
674+ do {
675+ prog[*fixup_map_array_ro].imm = map_fds[14];
676+ fixup_map_array_ro++;
677+ } while (*fixup_map_array_ro);
678+ }
679+ if (*fixup_map_array_wo) {
680+ map_fds[15] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
681+ sizeof(struct test_val), 1,
682+ BPF_F_WRONLY_PROG);
683+ update_map(map_fds[15], 0);
684+ do {
685+ prog[*fixup_map_array_wo].imm = map_fds[15];
686+ fixup_map_array_wo++;
687+ } while (*fixup_map_array_wo);
688+ }
689+ if (*fixup_map_array_small) {
690+ map_fds[16] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int),
691+ 1, 1, 0);
692+ update_map(map_fds[16], 0);
693+ do {
694+ prog[*fixup_map_array_small].imm = map_fds[16];
695+ fixup_map_array_small++;
696+ } while (*fixup_map_array_small);
697+ }
655698 }
656699
657700 static int set_admin(bool admin)
tools/testing/selftests/bpf/verifier/array_access.c+159−0
@@ -217,3 +217,162 @@ · 216 unmodified lines
217217 .result = REJECT,
218218 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
219219 },
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_DW, 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+},
tools/testing/selftests/bpf/verifier/direct_value_access.c+347−0
@@ -0,0 +1,347 @@
1+{
2+ "direct map access, write test 1",
3+ .insns = {
4+ BPF_MOV64_IMM(BPF_REG_0, 1),
5+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
6+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
7+ BPF_EXIT_INSN(),
8+ },
9+ .fixup_map_array_48b = { 1 },
10+ .result = ACCEPT,
11+ .retval = 1,
12+},
13+{
14+ "direct map access, write test 2",
15+ .insns = {
16+ BPF_MOV64_IMM(BPF_REG_0, 1),
17+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 8),
18+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
19+ BPF_EXIT_INSN(),
20+ },
21+ .fixup_map_array_48b = { 1 },
22+ .result = ACCEPT,
23+ .retval = 1,
24+},
25+{
26+ "direct map access, write test 3",
27+ .insns = {
28+ BPF_MOV64_IMM(BPF_REG_0, 1),
29+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 8),
30+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 4242),
31+ BPF_EXIT_INSN(),
32+ },
33+ .fixup_map_array_48b = { 1 },
34+ .result = ACCEPT,
35+ .retval = 1,
36+},
37+{
38+ "direct map access, write test 4",
39+ .insns = {
40+ BPF_MOV64_IMM(BPF_REG_0, 1),
41+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 40),
42+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
43+ BPF_EXIT_INSN(),
44+ },
45+ .fixup_map_array_48b = { 1 },
46+ .result = ACCEPT,
47+ .retval = 1,
48+},
49+{
50+ "direct map access, write test 5",
51+ .insns = {
52+ BPF_MOV64_IMM(BPF_REG_0, 1),
53+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 32),
54+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 4242),
55+ BPF_EXIT_INSN(),
56+ },
57+ .fixup_map_array_48b = { 1 },
58+ .result = ACCEPT,
59+ .retval = 1,
60+},
61+{
62+ "direct map access, write test 6",
63+ .insns = {
64+ BPF_MOV64_IMM(BPF_REG_0, 1),
65+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 40),
66+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 4, 4242),
67+ BPF_EXIT_INSN(),
68+ },
69+ .fixup_map_array_48b = { 1 },
70+ .result = REJECT,
71+ .errstr = "R1 min value is outside of the array range",
72+},
73+{
74+ "direct map access, write test 7",
75+ .insns = {
76+ BPF_MOV64_IMM(BPF_REG_0, 1),
77+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, -1),
78+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 4, 4242),
79+ BPF_EXIT_INSN(),
80+ },
81+ .fixup_map_array_48b = { 1 },
82+ .result = REJECT,
83+ .errstr = "direct value offset of 4294967295 is not allowed",
84+},
85+{
86+ "direct map access, write test 8",
87+ .insns = {
88+ BPF_MOV64_IMM(BPF_REG_0, 1),
89+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1),
90+ BPF_ST_MEM(BPF_DW, BPF_REG_1, -1, 4242),
91+ BPF_EXIT_INSN(),
92+ },
93+ .fixup_map_array_48b = { 1 },
94+ .result = ACCEPT,
95+ .retval = 1,
96+},
97+{
98+ "direct map access, write test 9",
99+ .insns = {
100+ BPF_MOV64_IMM(BPF_REG_0, 1),
101+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 48),
102+ BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 4242),
103+ BPF_EXIT_INSN(),
104+ },
105+ .fixup_map_array_48b = { 1 },
106+ .result = REJECT,
107+ .errstr = "invalid access to map value pointer",
108+},
109+{
110+ "direct map access, write test 10",
111+ .insns = {
112+ BPF_MOV64_IMM(BPF_REG_0, 1),
113+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 47),
114+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
115+ BPF_EXIT_INSN(),
116+ },
117+ .fixup_map_array_48b = { 1 },
118+ .result = ACCEPT,
119+ .retval = 1,
120+},
121+{
122+ "direct map access, write test 11",
123+ .insns = {
124+ BPF_MOV64_IMM(BPF_REG_0, 1),
125+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 48),
126+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
127+ BPF_EXIT_INSN(),
128+ },
129+ .fixup_map_array_48b = { 1 },
130+ .result = REJECT,
131+ .errstr = "invalid access to map value pointer",
132+},
133+{
134+ "direct map access, write test 12",
135+ .insns = {
136+ BPF_MOV64_IMM(BPF_REG_0, 1),
137+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, (1<<29)),
138+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
139+ BPF_EXIT_INSN(),
140+ },
141+ .fixup_map_array_48b = { 1 },
142+ .result = REJECT,
143+ .errstr = "direct value offset of 536870912 is not allowed",
144+},
145+{
146+ "direct map access, write test 13",
147+ .insns = {
148+ BPF_MOV64_IMM(BPF_REG_0, 1),
149+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, (1<<29)-1),
150+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 4),
151+ BPF_EXIT_INSN(),
152+ },
153+ .fixup_map_array_48b = { 1 },
154+ .result = REJECT,
155+ .errstr = "invalid access to map value pointer, value_size=48 off=536870911",
156+},
157+{
158+ "direct map access, write test 14",
159+ .insns = {
160+ BPF_MOV64_IMM(BPF_REG_0, 1),
161+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 47),
162+ BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
163+ BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
164+ BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0),
165+ BPF_EXIT_INSN(),
166+ },
167+ .fixup_map_array_48b = { 1, 3 },
168+ .result = ACCEPT,
169+ .retval = 0xff,
170+},
171+{
172+ "direct map access, write test 15",
173+ .insns = {
174+ BPF_MOV64_IMM(BPF_REG_0, 1),
175+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
176+ BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
177+ BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
178+ BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
179+ BPF_EXIT_INSN(),
180+ },
181+ .fixup_map_array_48b = { 1, 3 },
182+ .result = ACCEPT,
183+ .retval = 0xffff,
184+},
185+{
186+ "direct map access, write test 16",
187+ .insns = {
188+ BPF_MOV64_IMM(BPF_REG_0, 1),
189+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
190+ BPF_LD_MAP_VALUE(BPF_REG_2, 0, 47),
191+ BPF_ST_MEM(BPF_H, BPF_REG_2, 0, 0xffff),
192+ BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
193+ BPF_EXIT_INSN(),
194+ },
195+ .fixup_map_array_48b = { 1, 3 },
196+ .result = REJECT,
197+ .errstr = "invalid access to map value, value_size=48 off=47 size=2",
198+},
199+{
200+ "direct map access, write test 17",
201+ .insns = {
202+ BPF_MOV64_IMM(BPF_REG_0, 1),
203+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 46),
204+ BPF_LD_MAP_VALUE(BPF_REG_2, 0, 46),
205+ BPF_ST_MEM(BPF_H, BPF_REG_2, 1, 0xffff),
206+ BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1, 0),
207+ BPF_EXIT_INSN(),
208+ },
209+ .fixup_map_array_48b = { 1, 3 },
210+ .result = REJECT,
211+ .errstr = "invalid access to map value, value_size=48 off=47 size=2",
212+},
213+{
214+ "direct map access, write test 18",
215+ .insns = {
216+ BPF_MOV64_IMM(BPF_REG_0, 1),
217+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
218+ BPF_ST_MEM(BPF_H, BPF_REG_1, 0, 42),
219+ BPF_EXIT_INSN(),
220+ },
221+ .fixup_map_array_small = { 1 },
222+ .result = REJECT,
223+ .errstr = "R1 min value is outside of the array range",
224+},
225+{
226+ "direct map access, write test 19",
227+ .insns = {
228+ BPF_MOV64_IMM(BPF_REG_0, 1),
229+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 0),
230+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
231+ BPF_EXIT_INSN(),
232+ },
233+ .fixup_map_array_small = { 1 },
234+ .result = ACCEPT,
235+ .retval = 1,
236+},
237+{
238+ "direct map access, write test 20",
239+ .insns = {
240+ BPF_MOV64_IMM(BPF_REG_0, 1),
241+ BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1),
242+ BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42),
243+ BPF_EXIT_INSN(),
244+ },
245+ .fixup_map_array_small = { 1 },
246+ .result = REJECT,
247+ .errstr = "invalid access to map value pointer",
248+},
249+{
250+ "direct map access, invalid insn test 1",
251+ .insns = {
252+ BPF_MOV64_IMM(BPF_REG_0, 1),
253+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0, 1, 0, 47),
254+ BPF_EXIT_INSN(),
255+ },
256+ .fixup_map_array_48b = { 1 },
257+ .result = REJECT,
258+ .errstr = "invalid bpf_ld_imm64 insn",
259+},
260+{
261+ "direct map access, invalid insn test 2",
262+ .insns = {
263+ BPF_MOV64_IMM(BPF_REG_0, 1),
264+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 1, 0, 0, 47),
265+ BPF_EXIT_INSN(),
266+ },
267+ .fixup_map_array_48b = { 1 },
268+ .result = REJECT,
269+ .errstr = "BPF_LD_IMM64 uses reserved fields",
270+},
271+{
272+ "direct map access, invalid insn test 3",
273+ .insns = {
274+ BPF_MOV64_IMM(BPF_REG_0, 1),
275+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, ~0, 0, 0, 47),
276+ BPF_EXIT_INSN(),
277+ },
278+ .fixup_map_array_48b = { 1 },
279+ .result = REJECT,
280+ .errstr = "BPF_LD_IMM64 uses reserved fields",
281+},
282+{
283+ "direct map access, invalid insn test 4",
284+ .insns = {
285+ BPF_MOV64_IMM(BPF_REG_0, 1),
286+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0, ~0, 0, 47),
287+ BPF_EXIT_INSN(),
288+ },
289+ .fixup_map_array_48b = { 1 },
290+ .result = REJECT,
291+ .errstr = "invalid bpf_ld_imm64 insn",
292+},
293+{
294+ "direct map access, invalid insn test 5",
295+ .insns = {
296+ BPF_MOV64_IMM(BPF_REG_0, 1),
297+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, ~0, ~0, 0, 47),
298+ BPF_EXIT_INSN(),
299+ },
300+ .fixup_map_array_48b = { 1 },
301+ .result = REJECT,
302+ .errstr = "invalid bpf_ld_imm64 insn",
303+},
304+{
305+ "direct map access, invalid insn test 6",
306+ .insns = {
307+ BPF_MOV64_IMM(BPF_REG_0, 1),
308+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, ~0, 0, 0, 0),
309+ BPF_EXIT_INSN(),
310+ },
311+ .fixup_map_array_48b = { 1 },
312+ .result = REJECT,
313+ .errstr = "BPF_LD_IMM64 uses reserved fields",
314+},
315+{
316+ "direct map access, invalid insn test 7",
317+ .insns = {
318+ BPF_MOV64_IMM(BPF_REG_0, 1),
319+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, ~0, 0, 0),
320+ BPF_EXIT_INSN(),
321+ },
322+ .fixup_map_array_48b = { 1 },
323+ .result = REJECT,
324+ .errstr = "invalid bpf_ld_imm64 insn",
325+},
326+{
327+ "direct map access, invalid insn test 8",
328+ .insns = {
329+ BPF_MOV64_IMM(BPF_REG_0, 1),
330+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, ~0, ~0, 0, 0),
331+ BPF_EXIT_INSN(),
332+ },
333+ .fixup_map_array_48b = { 1 },
334+ .result = REJECT,
335+ .errstr = "invalid bpf_ld_imm64 insn",
336+},
337+{
338+ "direct map access, invalid insn test 9",
339+ .insns = {
340+ BPF_MOV64_IMM(BPF_REG_0, 1),
341+ BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_FD, 0, 0, 0, 47),
342+ BPF_EXIT_INSN(),
343+ },
344+ .fixup_map_array_48b = { 1 },
345+ .result = REJECT,
346+ .errstr = "unrecognized bpf_ld_imm64 insn",
347+},