selftests/bpf: Bind an exclusive map through a continuous fd_array

Load the exclusive program of map_excl with the map in a continuous
fd_array rather than through its insns alone, which has to work, and
the other program the same way, which has to be refused. The two
programs used to be identical and so shared a digest; give the second
one a value of its own so that the kernel can tell them apart.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261019132203.3034698-3-memxor@gmail.com
This commit is contained in:
Kumar Kartikeya Dwivedi 2026-10-19 15:21:44 +02:00 committed by Alexei Starovoitov
parent 55f17779d6
commit c2e56c88f1
No known key found for this signature in database
2 changed files with 39 additions and 1 deletions

View File

@ -161,12 +161,49 @@ static void test_map_excl_create_validation(void)
ASSERT_EQ(fd, -EINVAL, "reject size with NULL hash pointer");
}
/*
* The exclusive map bound through a continuous fd_array rather than by an
* insn. The kernel resolves the array before it verifies the program, so it
* has to have the digest of the program at hand by then.
*/
static void test_map_excl_fd_array(void)
{
struct map_excl *skel = map_excl__open();
LIBBPF_OPTS(bpf_prog_load_opts, opts);
int err, fd, map_fd;
if (!ASSERT_OK_PTR(skel, "map_excl__open"))
return;
err = bpf_map__set_exclusive_program(skel->maps.excl_map, skel->progs.should_have_access);
if (!ASSERT_OK(err, "bpf_map__set_exclusive_program"))
goto out;
bpf_program__set_autoload(skel->progs.should_have_access, true);
bpf_program__set_autoload(skel->progs.should_not_have_access, true);
err = bpf_object__prepare(skel->obj);
if (!ASSERT_OK(err, "map_excl prepare"))
goto out;
map_fd = bpf_map__fd(skel->maps.excl_map);
opts.fd_array = &map_fd;
opts.fd_array_cnt = 1;
fd = bpf_program__clone(skel->progs.should_have_access, &opts);
if (ASSERT_GE(fd, 0, "exclusive program with the map in fd_array"))
close(fd);
fd = bpf_program__clone(skel->progs.should_not_have_access, &opts);
ASSERT_EQ(fd, -EACCES, "other program with the map in fd_array");
out:
map_excl__destroy(skel);
}
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_fd_array"))
test_map_excl_fd_array();
if (test__start_subtest("map_excl_no_map_in_map"))
test_map_excl_no_map_in_map();
if (test__start_subtest("map_excl_no_map_iter"))

View File

@ -27,7 +27,8 @@ int should_have_access(void *ctx)
SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
int should_not_have_access(void *ctx)
{
int key = 0, value = 0xdeadbeef;
/* a different value, so that the two programs do not share a digest */
int key = 0, value = 0xbaadf00d;
bpf_map_update_elem(&excl_map, &key, &value, 0);
return 0;