Skip to content

Commit f8b19ae

Browse files
slava-at-csAlexei Starovoitov
authored andcommitted
selftests/bpf: Add test for bpftool access to read-only protected maps
Add selftest cases that validate bpftool's expected behavior when accessing maps protected from modification via security_bpf_map. The test includes a BPF program attached to security_bpf_map with two maps: - A protected map that only allows read-only access - An unprotected map that allows full access The test script attaches the BPF program to security_bpf_map and verifies that for the bpftool map command: - Read access works on both maps - Write access fails on the protected map - Write access succeeds on the unprotected map - These behaviors remain consistent when the maps are pinned Signed-off-by: Slava Imameev <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d32179e commit f8b19ae

File tree

4 files changed

+490
-0
lines changed

4 files changed

+490
-0
lines changed

tools/testing/selftests/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ TEST_PROGS := test_kmod.sh \
109109
test_xdping.sh \
110110
test_bpftool_build.sh \
111111
test_bpftool.sh \
112+
test_bpftool_map.sh \
112113
test_bpftool_metadata.sh \
113114
test_doc_build.sh \
114115
test_xsk.sh \
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include "vmlinux.h"
4+
#include <bpf/bpf_tracing.h>
5+
#include <bpf/bpf_helpers.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
__u32 value_sum = 0;
10+
11+
SEC("iter/bpf_map_elem")
12+
int dump_bpf_map_values(struct bpf_iter__bpf_map_elem *ctx)
13+
{
14+
__u32 value = 0;
15+
16+
if (ctx->value == (void *)0)
17+
return 0;
18+
19+
bpf_probe_read_kernel(&value, sizeof(value), ctx->value);
20+
value_sum += value;
21+
return 0;
22+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include "vmlinux.h"
4+
#include <bpf/bpf_tracing.h>
5+
#include <bpf/bpf_helpers.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
#define EPERM 1 /* Operation not permitted */
10+
11+
/* From include/linux/mm.h. */
12+
#define FMODE_WRITE 0x2
13+
14+
struct map;
15+
16+
struct {
17+
__uint(type, BPF_MAP_TYPE_ARRAY);
18+
__type(key, __u32);
19+
__type(value, __u32);
20+
__uint(max_entries, 1);
21+
} prot_status_map SEC(".maps");
22+
23+
struct {
24+
__uint(type, BPF_MAP_TYPE_HASH);
25+
__type(key, __u32);
26+
__type(value, __u32);
27+
__uint(max_entries, 3);
28+
} prot_map SEC(".maps");
29+
30+
struct {
31+
__uint(type, BPF_MAP_TYPE_HASH);
32+
__type(key, __u32);
33+
__type(value, __u32);
34+
__uint(max_entries, 3);
35+
} not_prot_map SEC(".maps");
36+
37+
SEC("fmod_ret/security_bpf_map")
38+
int BPF_PROG(fmod_bpf_map, struct bpf_map *map, int fmode)
39+
{
40+
__u32 key = 0;
41+
__u32 *status_ptr = bpf_map_lookup_elem(&prot_status_map, &key);
42+
43+
if (!status_ptr || !*status_ptr)
44+
return 0;
45+
46+
if (map == &prot_map) {
47+
/* Allow read-only access */
48+
if (fmode & FMODE_WRITE)
49+
return -EPERM;
50+
}
51+
52+
return 0;
53+
}
54+
55+
/*
56+
* This program keeps references to maps. This is needed to prevent
57+
* optimizing them out.
58+
*/
59+
SEC("fentry/bpf_fentry_test1")
60+
int BPF_PROG(fentry_dummy1, int a)
61+
{
62+
__u32 key = 0;
63+
__u32 val1 = a;
64+
__u32 val2 = a + 1;
65+
66+
bpf_map_update_elem(&prot_map, &key, &val1, BPF_ANY);
67+
bpf_map_update_elem(&not_prot_map, &key, &val2, BPF_ANY);
68+
return 0;
69+
}

0 commit comments

Comments
 (0)