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