xref: /linux/tools/testing/selftests/bpf/prog_tests/arena_direct_value.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <test_progs.h>
4 #include <bpf/bpf.h>
5 #include <errno.h>
6 #include <sys/mman.h>
7 #include <unistd.h>
8 
9 #define ARENA_PAGES 32
10 
11 static char log_buf[16384];
12 
test_arena_direct_value_one_past_end(void)13 static void test_arena_direct_value_one_past_end(void)
14 {
15 	char expected[128];
16 	__u32 arena_sz = ARENA_PAGES * getpagesize();
17 	struct bpf_insn insns[] = {
18 		BPF_LD_IMM64_RAW(BPF_REG_1, BPF_PSEUDO_MAP_VALUE, 0),
19 		BPF_MOV64_IMM(BPF_REG_0, 0),
20 		BPF_EXIT_INSN(),
21 	};
22 	LIBBPF_OPTS(bpf_map_create_opts, map_opts);
23 	LIBBPF_OPTS(bpf_prog_load_opts, prog_opts);
24 	void *arena;
25 	int map_fd, prog_fd;
26 
27 	map_opts.map_flags = BPF_F_MMAPABLE;
28 	prog_opts.log_buf = log_buf;
29 	prog_opts.log_size = sizeof(log_buf);
30 	prog_opts.log_level = 1;
31 
32 	map_fd = bpf_map_create(BPF_MAP_TYPE_ARENA, "arena_direct_value",
33 				0, 0, ARENA_PAGES, &map_opts);
34 	if (map_fd < 0) {
35 		if (errno == EOPNOTSUPP) {
36 			test__skip();
37 			return;
38 		}
39 		ASSERT_GE(map_fd, 0, "bpf_map_create");
40 		return;
41 	}
42 
43 	arena = mmap(NULL, arena_sz, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
44 	if (!ASSERT_NEQ(arena, MAP_FAILED, "arena_mmap"))
45 		goto cleanup;
46 
47 	insns[0].imm = map_fd;
48 	insns[1].imm = arena_sz;
49 
50 	prog_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT,
51 				"arena_direct_value", "GPL", insns,
52 				ARRAY_SIZE(insns), &prog_opts);
53 	if (!ASSERT_LT(prog_fd, 0, "prog_load")) {
54 		close(prog_fd);
55 		goto cleanup;
56 	}
57 
58 	snprintf(expected, sizeof(expected),
59 		 "invalid access to map value pointer, value_size=0 off=%u",
60 		 arena_sz);
61 	ASSERT_HAS_SUBSTR(log_buf, expected, "verifier_log");
62 
63 cleanup:
64 	if (arena != MAP_FAILED)
65 		munmap(arena, arena_sz);
66 	close(map_fd);
67 }
68 
serial_test_arena_direct_value(void)69 void serial_test_arena_direct_value(void)
70 {
71 	if (test__start_subtest("one_past_end"))
72 		test_arena_direct_value_one_past_end();
73 }
74