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