Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Daniel Borkmann and committed by
Alexei Starovoitov
fb2abb73 817998af

+573 -5
+20 -1
tools/include/linux/filter.h
··· 278 278 .off = 0, \ 279 279 .imm = ((__u64) (IMM)) >> 32 }) 280 280 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 + 281 295 /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */ 282 296 283 297 #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) 285 304 286 305 /* Relative call */ 287 306
+47 -4
tools/testing/selftests/bpf/test_verifier.c
··· 52 52 #define MAX_INSNS BPF_MAXINSNS 53 53 #define MAX_TEST_INSNS 1000000 54 54 #define MAX_FIXUPS 8 55 - #define MAX_NR_MAPS 14 55 + #define MAX_NR_MAPS 16 56 56 #define MAX_TEST_RUNS 8 57 57 #define POINTER_VALUE 0xcafe4all 58 58 #define TEST_DATA_LEN 64 ··· 82 82 int fixup_cgroup_storage[MAX_FIXUPS]; 83 83 int fixup_percpu_cgroup_storage[MAX_FIXUPS]; 84 84 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]; 85 88 const char *errstr; 86 89 const char *errstr_unpriv; 87 90 uint32_t retval, retval_unpriv, insn_processed; ··· 288 285 return false; 289 286 } 290 287 291 - static int create_map(uint32_t type, uint32_t size_key, 292 - uint32_t size_value, uint32_t max_elem) 288 + static int __create_map(uint32_t type, uint32_t size_key, 289 + uint32_t size_value, uint32_t max_elem, 290 + uint32_t extra_flags) 293 291 { 294 292 int fd; 295 293 296 294 fd = bpf_create_map(type, size_key, size_value, max_elem, 297 - type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0); 295 + (type == BPF_MAP_TYPE_HASH ? 296 + BPF_F_NO_PREALLOC : 0) | extra_flags); 298 297 if (fd < 0) { 299 298 if (skip_unsupported_map(type)) 300 299 return -1; ··· 304 299 } 305 300 306 301 return fd; 302 + } 303 + 304 + static int create_map(uint32_t type, uint32_t size_key, 305 + uint32_t size_value, uint32_t max_elem) 306 + { 307 + return __create_map(type, size_key, size_value, max_elem, 0); 307 308 } 308 309 309 310 static void update_map(int fd, int index) ··· 538 527 int *fixup_cgroup_storage = test->fixup_cgroup_storage; 539 528 int *fixup_percpu_cgroup_storage = test->fixup_percpu_cgroup_storage; 540 529 int *fixup_map_spin_lock = test->fixup_map_spin_lock; 530 + int *fixup_map_array_ro = test->fixup_map_array_ro; 531 + int *fixup_map_array_wo = test->fixup_map_array_wo; 532 + int *fixup_map_array_small = test->fixup_map_array_small; 541 533 542 534 if (test->fill_helper) { 543 535 test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn)); ··· 665 651 prog[*fixup_map_spin_lock].imm = map_fds[13]; 666 652 fixup_map_spin_lock++; 667 653 } while (*fixup_map_spin_lock); 654 + } 655 + if (*fixup_map_array_ro) { 656 + map_fds[14] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), 657 + sizeof(struct test_val), 1, 658 + BPF_F_RDONLY_PROG); 659 + update_map(map_fds[14], 0); 660 + do { 661 + prog[*fixup_map_array_ro].imm = map_fds[14]; 662 + fixup_map_array_ro++; 663 + } while (*fixup_map_array_ro); 664 + } 665 + if (*fixup_map_array_wo) { 666 + map_fds[15] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), 667 + sizeof(struct test_val), 1, 668 + BPF_F_WRONLY_PROG); 669 + update_map(map_fds[15], 0); 670 + do { 671 + prog[*fixup_map_array_wo].imm = map_fds[15]; 672 + fixup_map_array_wo++; 673 + } while (*fixup_map_array_wo); 674 + } 675 + if (*fixup_map_array_small) { 676 + map_fds[16] = __create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), 677 + 1, 1, 0); 678 + update_map(map_fds[16], 0); 679 + do { 680 + prog[*fixup_map_array_small].imm = map_fds[16]; 681 + fixup_map_array_small++; 682 + } while (*fixup_map_array_small); 668 683 } 669 684 } 670 685
+159
tools/testing/selftests/bpf/verifier/array_access.c
··· 217 217 .result = REJECT, 218 218 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 219 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_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 + },
+347
tools/testing/selftests/bpf/verifier/direct_value_access.c
··· 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 + },