selftests/bpf: Test that exclusive maps are rejected in map-in-map

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>
This commit is contained in:
Daniel Borkmann 2026-06-01 17:02:48 +02:00 committed by Alexei Starovoitov
parent 38498c0eba
commit 32f725458a

View 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 @@ static void test_map_excl_denied(void)
}
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();
}