xref: /linux/tools/testing/selftests/bpf/prog_tests/bpftool_maps_access.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1*2d96bbdfSAlexis Lothoré (eBPF Foundation) // SPDX-License-Identifier: GPL-2.0-only
2*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
3*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <stdlib.h>
4*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <unistd.h>
5*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <fcntl.h>
6*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <stdint.h>
7*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <sys/stat.h>
8*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <stdbool.h>
9*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <linux/bpf.h>
10*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <bpf/libbpf.h>
11*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <bpftool_helpers.h>
12*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <test_progs.h>
13*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include <bpf/bpf.h>
14*2d96bbdfSAlexis Lothoré (eBPF Foundation) #include "security_bpf_map.skel.h"
15*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
16*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define PROTECTED_MAP_NAME	"prot_map"
17*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define UNPROTECTED_MAP_NAME	"not_prot_map"
18*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define BPF_ITER_FILE		"bpf_iter_map_elem.bpf.o"
19*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define BPFFS_PIN_DIR		"/sys/fs/bpf/test_bpftool_map"
20*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define INNER_MAP_NAME		"inner_map_tt"
21*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define OUTER_MAP_NAME		"outer_map_tt"
22*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
23*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define MAP_NAME_MAX_LEN	64
24*2d96bbdfSAlexis Lothoré (eBPF Foundation) #define PATH_MAX_LEN		128
25*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
26*2d96bbdfSAlexis Lothoré (eBPF Foundation) enum map_protection {
27*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	PROTECTED,
28*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	UNPROTECTED
29*2d96bbdfSAlexis Lothoré (eBPF Foundation) };
30*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
31*2d96bbdfSAlexis Lothoré (eBPF Foundation) struct test_desc {
32*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char *name;
33*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	enum map_protection protection;
34*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	struct bpf_map *map;
35*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char *map_name;
36*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	bool pinned;
37*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char pin_path[PATH_MAX_LEN];
38*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	bool write_must_fail;
39*2d96bbdfSAlexis Lothoré (eBPF Foundation) };
40*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
41*2d96bbdfSAlexis Lothoré (eBPF Foundation) static struct security_bpf_map *general_setup(void)
42*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
43*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	struct security_bpf_map *skel;
44*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	uint32_t key, value;
45*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret, i;
46*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
47*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	skel = security_bpf_map__open_and_load();
48*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK_PTR(skel, "open and load skeleton"))
49*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto end;
50*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
51*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	struct bpf_map *maps[] = {skel->maps.prot_map, skel->maps.not_prot_map};
52*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
53*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = security_bpf_map__attach(skel);
54*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK(ret, "attach maps security programs"))
55*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto end_destroy;
56*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
57*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	for (i = 0; i < sizeof(maps)/sizeof(struct bpf_map *); i++) {
58*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		for (key = 0; key < 2; key++) {
59*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			int ret = bpf_map__update_elem(maps[i], &key,
60*2d96bbdfSAlexis Lothoré (eBPF Foundation) 					sizeof(key), &key, sizeof(key),
61*2d96bbdfSAlexis Lothoré (eBPF Foundation) 					0);
62*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			if (!ASSERT_OK(ret, "set initial map value"))
63*2d96bbdfSAlexis Lothoré (eBPF Foundation) 				goto end_destroy;
64*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		}
65*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
66*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
67*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	key = 0;
68*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	value = 1;
69*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = bpf_map__update_elem(skel->maps.prot_status_map, &key,
70*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			sizeof(key), &value, sizeof(value), 0);
71*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK(ret, "configure map protection"))
72*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto end_destroy;
73*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
74*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK(mkdir(BPFFS_PIN_DIR, S_IFDIR), "create bpffs pin dir"))
75*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto end_destroy;
76*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
77*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return skel;
78*2d96bbdfSAlexis Lothoré (eBPF Foundation) end_destroy:
79*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	security_bpf_map__destroy(skel);
80*2d96bbdfSAlexis Lothoré (eBPF Foundation) end:
81*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return NULL;
82*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
83*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
84*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void general_cleanup(struct security_bpf_map *skel)
85*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
86*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	rmdir(BPFFS_PIN_DIR);
87*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	security_bpf_map__destroy(skel);
88*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
89*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
90*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void update_test_desc(struct security_bpf_map *skel,
91*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			      struct test_desc *test)
92*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
93*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	/* Now that the skeleton is loaded, update all missing fields to
94*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	 * have the subtest properly configured
95*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	 */
96*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (test->protection == PROTECTED) {
97*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test->map = skel->maps.prot_map;
98*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test->map_name = PROTECTED_MAP_NAME;
99*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	} else {
100*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test->map = skel->maps.not_prot_map;
101*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test->map_name = UNPROTECTED_MAP_NAME;
102*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
103*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
104*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
105*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int test_setup(struct security_bpf_map *skel, struct test_desc *desc)
106*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
107*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret;
108*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
109*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	update_test_desc(skel, desc);
110*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
111*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (desc->pinned) {
112*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ret = snprintf(desc->pin_path, PATH_MAX_LEN, "%s/%s", BPFFS_PIN_DIR,
113*2d96bbdfSAlexis Lothoré (eBPF Foundation) 				desc->name);
114*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		if (!ASSERT_GT(ret, 0, "format pin path"))
115*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			return 1;
116*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ret = bpf_map__pin(desc->map, desc->pin_path);
117*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		if (!ASSERT_OK(ret, "pin map"))
118*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			return 1;
119*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
120*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
121*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return 0;
122*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
123*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
124*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void test_cleanup(struct test_desc *desc)
125*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
126*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (desc->pinned)
127*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		bpf_map__unpin(desc->map, NULL);
128*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
129*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
130*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int lookup_map_value(char *map_handle)
131*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
132*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
133*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
134*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
135*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAX_BPFTOOL_CMD_LEN, "map lookup %s key 0 0 0 0",
136*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			map_handle);
137*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format map lookup cmd"))
138*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
139*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
140*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
141*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
142*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int read_map_btf_data(char *map_handle)
143*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
144*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
145*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
146*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
147*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAX_BPFTOOL_CMD_LEN, "btf dump map %s",
148*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			map_handle);
149*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format map btf dump cmd"))
150*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
151*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
152*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
153*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
154*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int write_map_value(char *map_handle)
155*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
156*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
157*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
158*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
159*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAX_BPFTOOL_CMD_LEN,
160*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		       "map update %s key 0 0 0 0 value 1 1 1 1", map_handle);
161*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format value write cmd"))
162*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
163*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
164*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
165*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
166*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int delete_map_value(char *map_handle)
167*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
168*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
169*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
170*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
171*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAX_BPFTOOL_CMD_LEN,
172*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		       "map delete %s key 0 0 0 0", map_handle);
173*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format value deletion cmd"))
174*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
175*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
176*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
177*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
178*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int iterate_on_map_values(char *map_handle, char *iter_pin_path)
179*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
180*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
181*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
182*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
183*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
184*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAX_BPFTOOL_CMD_LEN, "iter pin %s %s map %s",
185*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		       BPF_ITER_FILE, iter_pin_path, map_handle);
186*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format iterator creation cmd"))
187*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
188*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = run_bpftool_command(cmd);
189*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (ret)
190*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return ret;
191*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(cmd, MAP_NAME_MAX_LEN, "cat %s", iter_pin_path);
192*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (ret < 0)
193*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto cleanup;
194*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = system(cmd);
195*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
196*2d96bbdfSAlexis Lothoré (eBPF Foundation) cleanup:
197*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	unlink(iter_pin_path);
198*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return ret;
199*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
200*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
201*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int create_inner_map(void)
202*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
203*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
204*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
205*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
206*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(
207*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		cmd, MAX_BPFTOOL_CMD_LEN,
208*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		"map create %s/%s type array key 4 value 4 entries 4 name %s",
209*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		BPFFS_PIN_DIR, INNER_MAP_NAME, INNER_MAP_NAME);
210*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format inner map create cmd"))
211*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
212*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
213*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
214*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
215*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int create_outer_map(void)
216*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
217*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
218*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
219*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
220*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(
221*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		cmd, MAX_BPFTOOL_CMD_LEN,
222*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		"map create %s/%s type hash_of_maps key 4 value 4 entries 2 name %s inner_map name %s",
223*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		BPFFS_PIN_DIR, OUTER_MAP_NAME, OUTER_MAP_NAME, INNER_MAP_NAME);
224*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format outer map create cmd"))
225*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
226*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
227*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
228*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
229*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void delete_pinned_map(char *map_name)
230*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
231*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char pin_path[PATH_MAX_LEN];
232*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret;
233*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
234*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(pin_path, PATH_MAX_LEN, "%s/%s", BPFFS_PIN_DIR,
235*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		       map_name);
236*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (ret >= 0)
237*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		unlink(pin_path);
238*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
239*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
240*2d96bbdfSAlexis Lothoré (eBPF Foundation) static int add_outer_map_entry(int key)
241*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
242*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char cmd[MAX_BPFTOOL_CMD_LEN];
243*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret = 0;
244*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
245*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(
246*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		cmd, MAX_BPFTOOL_CMD_LEN,
247*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		"map update pinned %s/%s key %d 0 0 0 value name %s",
248*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		BPFFS_PIN_DIR, OUTER_MAP_NAME, key, INNER_MAP_NAME);
249*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format outer map value addition cmd"))
250*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return 1;
251*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	return run_bpftool_command(cmd);
252*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
253*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
254*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void test_basic_access(struct test_desc *desc)
255*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
256*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char map_handle[MAP_NAME_MAX_LEN];
257*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	char iter_pin_path[PATH_MAX_LEN];
258*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int ret;
259*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
260*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (desc->pinned)
261*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ret = snprintf(map_handle, MAP_NAME_MAX_LEN, "pinned %s",
262*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			       desc->pin_path);
263*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	else
264*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ret = snprintf(map_handle, MAP_NAME_MAX_LEN, "name %s",
265*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			       desc->map_name);
266*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_GT(ret, 0, "format map handle"))
267*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return;
268*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
269*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = lookup_map_value(map_handle);
270*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(ret, "read map value");
271*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
272*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = read_map_btf_data(map_handle);
273*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(ret, "read map btf data");
274*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
275*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = write_map_value(map_handle);
276*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(desc->write_must_fail ? !ret : ret, "write map value");
277*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
278*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = delete_map_value(map_handle);
279*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(desc->write_must_fail ? !ret : ret, "delete map value");
280*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	/* Restore deleted value */
281*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ret)
282*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		write_map_value(map_handle);
283*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
284*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ret = snprintf(iter_pin_path, PATH_MAX_LEN, "%s/iter", BPFFS_PIN_DIR);
285*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (ASSERT_GT(ret, 0, "format iter pin path")) {
286*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ret = iterate_on_map_values(map_handle, iter_pin_path);
287*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		ASSERT_OK(ret, "iterate on map values");
288*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
289*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
290*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
291*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void test_create_nested_maps(void)
292*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
293*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK(create_inner_map(), "create inner map"))
294*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		return;
295*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK(create_outer_map(), "create outer map"))
296*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto end_cleanup_inner;
297*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(add_outer_map_entry(0), "add a first entry in outer map");
298*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(add_outer_map_entry(1), "add a second entry in outer map");
299*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_NEQ(add_outer_map_entry(2), 0, "add a third entry in outer map");
300*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
301*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	delete_pinned_map(OUTER_MAP_NAME);
302*2d96bbdfSAlexis Lothoré (eBPF Foundation) end_cleanup_inner:
303*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	delete_pinned_map(INNER_MAP_NAME);
304*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
305*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
306*2d96bbdfSAlexis Lothoré (eBPF Foundation) static void test_btf_list(void)
307*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
308*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	ASSERT_OK(run_bpftool_command("btf list"), "list btf data");
309*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
310*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
311*2d96bbdfSAlexis Lothoré (eBPF Foundation) static struct test_desc tests[] = {
312*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	{
313*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.name = "unprotected_unpinned",
314*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.protection = UNPROTECTED,
315*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.map_name = UNPROTECTED_MAP_NAME,
316*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.pinned = false,
317*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.write_must_fail = false,
318*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	},
319*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	{
320*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.name = "unprotected_pinned",
321*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.protection = UNPROTECTED,
322*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.map_name = UNPROTECTED_MAP_NAME,
323*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.pinned = true,
324*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.write_must_fail = false,
325*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	},
326*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	{
327*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.name = "protected_unpinned",
328*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.protection = PROTECTED,
329*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.map_name = UNPROTECTED_MAP_NAME,
330*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.pinned = false,
331*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.write_must_fail = true,
332*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	},
333*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	{
334*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.name = "protected_pinned",
335*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.protection = PROTECTED,
336*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.map_name = UNPROTECTED_MAP_NAME,
337*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.pinned = true,
338*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		.write_must_fail = true,
339*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
340*2d96bbdfSAlexis Lothoré (eBPF Foundation) };
341*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
342*2d96bbdfSAlexis Lothoré (eBPF Foundation) static const size_t tests_count = ARRAY_SIZE(tests);
343*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
344*2d96bbdfSAlexis Lothoré (eBPF Foundation) void test_bpftool_maps_access(void)
345*2d96bbdfSAlexis Lothoré (eBPF Foundation) {
346*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	struct security_bpf_map *skel;
347*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	struct test_desc *current;
348*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	int i;
349*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
350*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	skel = general_setup();
351*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (!ASSERT_OK_PTR(skel, "prepare programs"))
352*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		goto cleanup;
353*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
354*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	for (i = 0; i < tests_count; i++) {
355*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		current = &tests[i];
356*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		if (!test__start_subtest(current->name))
357*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			continue;
358*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		if (ASSERT_OK(test_setup(skel, current), "subtest setup")) {
359*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			test_basic_access(current);
360*2d96bbdfSAlexis Lothoré (eBPF Foundation) 			test_cleanup(current);
361*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		}
362*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	}
363*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (test__start_subtest("nested_maps"))
364*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test_create_nested_maps();
365*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	if (test__start_subtest("btf_list"))
366*2d96bbdfSAlexis Lothoré (eBPF Foundation) 		test_btf_list();
367*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
368*2d96bbdfSAlexis Lothoré (eBPF Foundation) cleanup:
369*2d96bbdfSAlexis Lothoré (eBPF Foundation) 	general_cleanup(skel);
370*2d96bbdfSAlexis Lothoré (eBPF Foundation) }
371*2d96bbdfSAlexis Lothoré (eBPF Foundation) 
372