All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Fastabend <john.fastabend@gmail.com>
To: bpf@vger.kernel.org
Cc: john.fastabend@gmail.com, daniel@iogearbox.net
Subject: [PATCH bpf-next 2/2] libbpf: selftest for bpf_map__reuse_fd_from_loader_ctx()
Date: Fri, 26 Jun 2026 14:51:13 -0700	[thread overview]
Message-ID: <20260626215113.52273-2-john.fastabend@gmail.com> (raw)
In-Reply-To: <20260626215113.52273-1-john.fastabend@gmail.com>

Extend signed loader test case to exercise __reuse_fd_from_loader_ctx().

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 .../selftests/bpf/prog_tests/signed_loader.c  | 115 ++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/signed_loader.c b/tools/testing/selftests/bpf/prog_tests/signed_loader.c
index 5fc417e31fc6..0af33362ab1b 100644
--- a/tools/testing/selftests/bpf/prog_tests/signed_loader.c
+++ b/tools/testing/selftests/bpf/prog_tests/signed_loader.c
@@ -8,8 +8,10 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <unistd.h>
 #include <linux/keyctl.h>
 #include <linux/bpf.h>
+#include <linux/if_ether.h>
 
 #include "bpf/libbpf_internal.h" /* for libbpf_sha256() */
 #include "bpf/skel_internal.h"	 /* for loader ctx layout (bpf_loader_ctx etc) */
@@ -699,6 +701,117 @@ static void metadata_ctx_initial_value_ignored(void)
 	test_signed_loader_data__destroy(skel);
 }
 
+static void loader_ctx_reuse_fd_shared_map(void)
+{
+	LIBBPF_OPTS(gen_loader_opts, gopts, .gen_hash = true);
+	struct test_signed_loader_map *skel = NULL;
+	struct bpf_map_info shared_info, reused_info;
+	__u32 shared_info_len, reused_info_len;
+	__u8 excl[SHA256_DIGEST_LENGTH];
+	__u8 pkt[ETH_HLEN] = {};
+	__u32 key = 0, expected_retval = 42;
+	__u64 shared_value = expected_retval;
+	LIBBPF_OPTS(bpf_test_run_opts, topts,
+		.data_in = pkt,
+		.data_size_in = sizeof(pkt),
+		.repeat = 1,
+	);
+	int nr_maps = 0, nr_progs = 0, ctx_fd = -1, shared_fd = -1;
+	int supplied_fd, r;
+	struct bpf_prog_desc *pd;
+	struct bpf_map_desc *md;
+	struct bpf_program *p;
+	struct bpf_map *m;
+	unsigned char *blob = NULL;
+	__u32 ctx_sz, data_sz;
+	void *ctx = NULL;
+	bool ran;
+
+	skel = test_signed_loader_map__open();
+	if (!ASSERT_OK_PTR(skel, "skel_open"))
+		goto cleanup;
+	if (!ASSERT_OK(bpf_map__reuse_fd_from_loader_ctx(skel->maps.amap),
+		       "reuse_fd_from_loader_ctx"))
+		goto cleanup;
+	if (!ASSERT_OK(bpf_object__gen_loader(skel->obj, &gopts), "gen_loader"))
+		goto cleanup;
+	if (!ASSERT_OK(bpf_object__load(skel->obj), "gen_load"))
+		goto cleanup;
+
+	bpf_object__for_each_program(p, skel->obj)
+		nr_progs++;
+	bpf_object__for_each_map(m, skel->obj)
+		nr_maps++;
+	if (!ASSERT_EQ(nr_maps, 1, "one map") ||
+	    !ASSERT_EQ(nr_progs, 1, "one prog"))
+		goto cleanup;
+
+	shared_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "ctx_reuse",
+				   sizeof(__u32), sizeof(__u64), 4, NULL);
+	if (!ASSERT_OK_FD(shared_fd, "shared_map"))
+		goto cleanup;
+	if (!ASSERT_OK(bpf_map_update_elem(shared_fd, &key, &shared_value, BPF_ANY),
+		       "shared_map_update"))
+		goto cleanup;
+
+	ctx_sz = sizeof(struct bpf_loader_ctx) +
+		 nr_maps * sizeof(struct bpf_map_desc) +
+		 nr_progs * sizeof(struct bpf_prog_desc);
+	ctx = calloc(1, ctx_sz);
+	if (!ASSERT_OK_PTR(ctx, "ctx_alloc"))
+		goto cleanup;
+	((struct bpf_loader_ctx *)ctx)->sz = ctx_sz;
+
+	md = (struct bpf_map_desc *)((char *)ctx + sizeof(struct bpf_loader_ctx));
+	pd = (struct bpf_prog_desc *)(md + nr_maps);
+	ctx_fd = dup(shared_fd);
+	if (!ASSERT_OK_FD(ctx_fd, "ctx_map_fd"))
+		goto cleanup;
+	md[0].map_fd = ctx_fd;
+	ctx_fd = -1;
+	supplied_fd = md[0].map_fd;
+
+	libbpf_sha256(gopts.insns, gopts.insns_sz, excl);
+	data_sz = gopts.data_sz;
+	blob = malloc(data_sz);
+	if (!ASSERT_OK_PTR(blob, "blob_alloc"))
+		goto cleanup;
+	memcpy(blob, gopts.data, data_sz);
+
+	r = run_gen_loader(gopts.insns, gopts.insns_sz, blob, data_sz,
+			   excl, sizeof(excl), NULL, 0, true, ctx, ctx_sz, &ran);
+	if (!ASSERT_TRUE(ran, "loader ran") ||
+	    !ASSERT_EQ(r, 0, "loader retval"))
+		goto cleanup;
+
+	ASSERT_EQ(md[0].map_fd, supplied_fd, "ctx map fd preserved");
+	ASSERT_GT(pd[0].prog_fd, 0, "prog fd populated");
+	if (ASSERT_OK(bpf_prog_test_run_opts(pd[0].prog_fd, &topts),
+		      "shared map prog run"))
+		ASSERT_EQ(topts.retval, expected_retval, "shared map value");
+
+	memset(&shared_info, 0, sizeof(shared_info));
+	memset(&reused_info, 0, sizeof(reused_info));
+	shared_info_len = sizeof(shared_info);
+	reused_info_len = sizeof(reused_info);
+	if (ASSERT_OK(bpf_map_get_info_by_fd(shared_fd, &shared_info, &shared_info_len),
+		      "shared map info") &&
+	    ASSERT_OK(bpf_map_get_info_by_fd(md[0].map_fd, &reused_info, &reused_info_len),
+		      "reused map info"))
+		ASSERT_EQ(reused_info.id, shared_info.id, "shared map reused");
+
+cleanup:
+	if (ctx)
+		close_loader_ctx_fds(ctx, nr_maps, nr_progs);
+	if (ctx_fd >= 0)
+		close(ctx_fd);
+	if (shared_fd >= 0)
+		close(shared_fd);
+	free(blob);
+	free(ctx);
+	test_signed_loader_map__destroy(skel);
+}
+
 /*
  * The load-time signature must authenticate the loader instructions: a valid
  * signature loads, and the very same signature over one-byte-tampered insns is
@@ -1112,6 +1225,8 @@ void test_signed_loader(void)
 		metadata_ctx_max_entries_ignored();
 	if (test__start_subtest("metadata_ctx_initial_value_ignored"))
 		metadata_ctx_initial_value_ignored();
+	if (test__start_subtest("loader_ctx_reuse_fd_shared_map"))
+		loader_ctx_reuse_fd_shared_map();
 	if (test__start_subtest("signature_authenticates_insns"))
 		signature_authenticates_insns();
 	if (test__start_subtest("hash_requires_frozen"))
-- 
2.53.0


      reply	other threads:[~2026-06-26 21:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-26 21:51 [PATCH bpf-next 1/2] libbpf: add bpf_map__reuse_fd_from_loader_ctx() to allow shared maps John Fastabend
2026-06-26 21:51 ` John Fastabend [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260626215113.52273-2-john.fastabend@gmail.com \
    --to=john.fastabend@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.