]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Test that exclusive maps are rejected in map-in-map
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 1 Jun 2026 15:02:48 +0000 (17:02 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 2 Jun 2026 01:36:41 +0000 (18:36 -0700)
Add a subtest to map_excl that verifies an exclusive map (created with
excl_prog_hash) cannot be used in a map-of-maps, covering both kernel
enforcement points: i) the inner-map template at map-of-maps creation
and, ii) the element inserted into an existing map-of-maps.

  # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t map_excl
  ./test_progs -t map_excl
  [    1.728106] bpf_testmod: loading out-of-tree module taints kernel.
  [    1.730473] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
  #215/1   map_excl/map_excl_allowed:OK
  #215/2   map_excl/map_excl_denied:OK
  #215/3   map_excl/map_excl_no_map_in_map:OK
  #215     map_excl:OK
  Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260601150248.394863-8-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/map_excl.c

index 6bdc6d6de0daf245c77165083819c990a16ef4f5..a213dd559aaecefed6ecd734718a8c754453d00a 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "map_excl.skel.h"
 
+#ifndef SHA256_DIGEST_SIZE
+#define SHA256_DIGEST_SIZE     32
+#endif
+
 static void test_map_excl_allowed(void)
 {
        struct map_excl *skel = map_excl__open();
@@ -45,10 +49,52 @@ out:
 
 }
 
+static void test_map_excl_no_map_in_map(void)
+{
+       __u8 hash[SHA256_DIGEST_SIZE] = {};
+       LIBBPF_OPTS(bpf_map_create_opts, excl_opts,
+                   .excl_prog_hash = hash,
+                   .excl_prog_hash_size = sizeof(hash));
+       LIBBPF_OPTS(bpf_map_create_opts, outer_opts);
+       int excl_fd, tmpl_fd = -1, outer_fd = -1, err;
+       __u32 key = 0;
+
+       excl_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "excl_inner", 4, 4, 1, &excl_opts);
+       if (!ASSERT_OK_FD(excl_fd, "create exclusive map"))
+               return;
+
+       outer_opts.inner_map_fd = excl_fd;
+       err = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS, "outer_from_excl",
+                            4, 4, 1, &outer_opts);
+       if (err >= 0)
+               close(err);
+       ASSERT_EQ(err, -ENOTSUPP, "reject exclusive map as map-in-map template");
+
+       tmpl_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "tmpl", 4, 4, 1, NULL);
+       if (!ASSERT_OK_FD(tmpl_fd, "create inner template"))
+               goto out;
+
+       outer_opts.inner_map_fd = tmpl_fd;
+       outer_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS, "outer", 4, 4, 1, &outer_opts);
+       if (!ASSERT_OK_FD(outer_fd, "create map-of-maps"))
+               goto out;
+
+       err = bpf_map_update_elem(outer_fd, &key, &excl_fd, 0);
+       ASSERT_EQ(err, -ENOTSUPP, "reject exclusive map as map-in-map element");
+out:
+       if (outer_fd >= 0)
+               close(outer_fd);
+       if (tmpl_fd >= 0)
+               close(tmpl_fd);
+       close(excl_fd);
+}
+
 void test_map_excl(void)
 {
        if (test__start_subtest("map_excl_allowed"))
                test_map_excl_allowed();
        if (test__start_subtest("map_excl_denied"))
                test_map_excl_denied();
+       if (test__start_subtest("map_excl_no_map_in_map"))
+               test_map_excl_no_map_in_map();
 }