1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2025 Google LLC. */ 3 #define _GNU_SOURCE 4 #include <unistd.h> 5 #include <sys/syscall.h> 6 #include <test_progs.h> 7 #include <bpf/btf.h> 8 9 #include "map_excl.skel.h" 10 11 #ifndef SHA256_DIGEST_SIZE 12 #define SHA256_DIGEST_SIZE 32 13 #endif 14 15 static void test_map_excl_allowed(void) 16 { 17 struct map_excl *skel = map_excl__open(); 18 int err; 19 20 err = bpf_map__set_exclusive_program(skel->maps.excl_map, skel->progs.should_have_access); 21 if (!ASSERT_OK(err, "bpf_map__set_exclusive_program")) 22 goto out; 23 24 bpf_program__set_autoload(skel->progs.should_have_access, true); 25 bpf_program__set_autoload(skel->progs.should_not_have_access, false); 26 27 err = map_excl__load(skel); 28 ASSERT_OK(err, "map_excl__load"); 29 out: 30 map_excl__destroy(skel); 31 } 32 33 static void test_map_excl_denied(void) 34 { 35 struct map_excl *skel = map_excl__open(); 36 int err; 37 38 err = bpf_map__set_exclusive_program(skel->maps.excl_map, skel->progs.should_have_access); 39 if (!ASSERT_OK(err, "bpf_map__make_exclusive")) 40 goto out; 41 42 bpf_program__set_autoload(skel->progs.should_have_access, false); 43 bpf_program__set_autoload(skel->progs.should_not_have_access, true); 44 45 err = map_excl__load(skel); 46 ASSERT_EQ(err, -EACCES, "exclusive map access not denied\n"); 47 out: 48 map_excl__destroy(skel); 49 50 } 51 52 static void test_map_excl_no_map_in_map(void) 53 { 54 __u8 hash[SHA256_DIGEST_SIZE] = {}; 55 LIBBPF_OPTS(bpf_map_create_opts, excl_opts, 56 .excl_prog_hash = hash, 57 .excl_prog_hash_size = sizeof(hash)); 58 LIBBPF_OPTS(bpf_map_create_opts, outer_opts); 59 int excl_fd, tmpl_fd = -1, outer_fd = -1, err; 60 __u32 key = 0; 61 62 excl_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "excl_inner", 4, 4, 1, &excl_opts); 63 if (!ASSERT_OK_FD(excl_fd, "create exclusive map")) 64 return; 65 66 outer_opts.inner_map_fd = excl_fd; 67 err = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS, "outer_from_excl", 68 4, 4, 1, &outer_opts); 69 if (err >= 0) 70 close(err); 71 ASSERT_EQ(err, -ENOTSUPP, "reject exclusive map as map-in-map template"); 72 73 tmpl_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "tmpl", 4, 4, 1, NULL); 74 if (!ASSERT_OK_FD(tmpl_fd, "create inner template")) 75 goto out; 76 77 outer_opts.inner_map_fd = tmpl_fd; 78 outer_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS, "outer", 4, 4, 1, &outer_opts); 79 if (!ASSERT_OK_FD(outer_fd, "create map-of-maps")) 80 goto out; 81 82 err = bpf_map_update_elem(outer_fd, &key, &excl_fd, 0); 83 ASSERT_EQ(err, -ENOTSUPP, "reject exclusive map as map-in-map element"); 84 out: 85 if (outer_fd >= 0) 86 close(outer_fd); 87 if (tmpl_fd >= 0) 88 close(tmpl_fd); 89 close(excl_fd); 90 } 91 92 void test_map_excl(void) 93 { 94 if (test__start_subtest("map_excl_allowed")) 95 test_map_excl_allowed(); 96 if (test__start_subtest("map_excl_denied")) 97 test_map_excl_denied(); 98 if (test__start_subtest("map_excl_no_map_in_map")) 99 test_map_excl_no_map_in_map(); 100 } 101