[PATCH 17/18] bpf-preload/selftests: Add test for automatic generation of preload methods
Roberto Sassu
roberto.sassu at huawei.com
Mon Mar 28 17:50:32 UTC 2022
Add the test 'gen_preload_methods' to ensure that the preload methods are
correctly generated. Introduce a sample eBPF program in
progs/gen_preload_methods.c, generate the light skeleton without and with
the preload methods, and finally compare the diff with the expected diff
output in prog_tests/gen_preload_methods.expected.diff.
Signed-off-by: Roberto Sassu <roberto.sassu at huawei.com>
---
tools/testing/selftests/bpf/Makefile | 15 ++-
.../gen_preload_methods.expected.diff | 97 +++++++++++++++++++
.../bpf/prog_tests/test_gen_preload_methods.c | 27 ++++++
.../selftests/bpf/progs/gen_preload_methods.c | 23 +++++
4 files changed, 160 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/gen_preload_methods.expected.diff
create mode 100644 tools/testing/selftests/bpf/prog_tests/test_gen_preload_methods.c
create mode 100644 tools/testing/selftests/bpf/progs/gen_preload_methods.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 3820608faf57..de81779e90e3 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -337,10 +337,11 @@ test_subskeleton_lib.skel.h-deps := test_subskeleton_lib2.o test_subskeleton_lib
LSKELS := kfunc_call_test.c fentry_test.c fexit_test.c fexit_sleep.c \
test_ringbuf.c atomics.c trace_printk.c trace_vprintk.c \
- map_ptr_kern.c core_kern.c core_kern_overflow.c
+ map_ptr_kern.c core_kern.c core_kern_overflow.c gen_preload_methods.c
+LSKELSP := gen_preload_methods.c
# Generate both light skeleton and libbpf skeleton for these
LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test_subprog.c
-SKEL_BLACKLIST += $$(LSKELS)
+SKEL_BLACKLIST += $$(LSKELS) $$(LSKELSP)
test_static_linked.skel.h-deps := test_static_linked1.o test_static_linked2.o
linked_funcs.skel.h-deps := linked_funcs1.o linked_funcs2.o
@@ -370,6 +371,7 @@ TRUNNER_BPF_SKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.skel.h, \
$$(filter-out $(SKEL_BLACKLIST) $(LINKED_BPF_SRCS),\
$$(TRUNNER_BPF_SRCS)))
TRUNNER_BPF_LSKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.lskel.h, $$(LSKELS) $$(LSKELS_EXTRA))
+TRUNNER_BPF_LSKELSP := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.preload.lskel.h, $$(LSKELSP))
TRUNNER_BPF_SKELS_LINKED := $$(addprefix $$(TRUNNER_OUTPUT)/,$(LINKED_SKELS))
TEST_GEN_FILES += $$(TRUNNER_BPF_OBJS)
@@ -421,6 +423,14 @@ $(TRUNNER_BPF_LSKELS): %.lskel.h: %.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
$(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
$(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.linked3.o) name $$(notdir $$(<:.o=_lskel)) > $$@
+$(TRUNNER_BPF_LSKELSP): %.preload.lskel.h: %.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
+ $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@)
+ $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked1.o) $$<
+ $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o)
+ $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o)
+ $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o)
+ $(Q)$$(BPFTOOL) gen skeleton -L -P $$(<:.o=.linked3.o) name $$(notdir $$(<:.o=_lskel)) > $$@
+
$(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_BPF_OBJS) $(BPFTOOL) | $(TRUNNER_OUTPUT)
$$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.o))
$(Q)$$(BPFTOOL) gen object $$(@:.skel.h=.linked1.o) $$(addprefix $(TRUNNER_OUTPUT)/,$$($$(@F)-deps))
@@ -451,6 +461,7 @@ $(TRUNNER_TEST_OBJS): $(TRUNNER_OUTPUT)/%.test.o: \
$(TRUNNER_BPF_OBJS) \
$(TRUNNER_BPF_SKELS) \
$(TRUNNER_BPF_LSKELS) \
+ $(TRUNNER_BPF_LSKELSP) \
$(TRUNNER_BPF_SKELS_LINKED) \
$$(BPFOBJ) | $(TRUNNER_OUTPUT)
$$(call msg,TEST-OBJ,$(TRUNNER_BINARY),$$@)
diff --git a/tools/testing/selftests/bpf/prog_tests/gen_preload_methods.expected.diff b/tools/testing/selftests/bpf/prog_tests/gen_preload_methods.expected.diff
new file mode 100644
index 000000000000..5e010d380e50
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/gen_preload_methods.expected.diff
@@ -0,0 +1,97 @@
+--- gen_preload_methods.lskel.h 2022-03-28 13:40:22.042715754 +0200
++++ gen_preload_methods.preload.lskel.h 2022-03-28 13:40:22.530715750 +0200
+@@ -221,4 +221,94 @@ gen_preload_methods_lskel__assert(struct
+ #endif
+ }
+
++static struct bpf_link *dump_bpf_map_link;
++static struct bpf_map *ringbuf_map;
++static struct gen_preload_methods_lskel *skel;
++
++static void free_objs_and_skel(void)
++{
++ bpf_preload_set_ops("gen_preload_methods_lskel", THIS_MODULE, NULL);
++
++ if (!IS_ERR_OR_NULL(dump_bpf_map_link))
++ bpf_link_put(dump_bpf_map_link);
++ if (!IS_ERR_OR_NULL(ringbuf_map))
++ bpf_map_put(ringbuf_map);
++
++ gen_preload_methods_lskel__destroy(skel);
++}
++
++static int preload(struct dentry *parent)
++{
++ int err;
++
++ bpf_link_inc(dump_bpf_map_link);
++ bpf_map_inc(ringbuf_map);
++
++ err = bpf_obj_do_pin_kernel(parent, "dump_bpf_map",
++ dump_bpf_map_link,
++ BPF_TYPE_LINK);
++ if (err)
++ goto undo;
++
++ err = bpf_obj_do_pin_kernel(parent, "ringbuf",
++ ringbuf_map,
++ BPF_TYPE_MAP);
++ if (err)
++ goto undo;
++
++ return 0;
++undo:
++ bpf_link_put(dump_bpf_map_link);
++ bpf_map_put(ringbuf_map);
++ return err;
++}
++
++static struct bpf_preload_ops ops = {
++ .preload = preload,
++ .owner = THIS_MODULE,
++};
++
++static int load_skel(void)
++{
++ int err = -ENOMEM;
++
++ if (!bpf_preload_set_ops("gen_preload_methods_lskel", THIS_MODULE, &ops))
++ return 0;
++
++ skel = gen_preload_methods_lskel__open();
++ if (!skel)
++ goto out;
++
++ err = gen_preload_methods_lskel__load(skel);
++ if (err)
++ goto out;
++
++ err = gen_preload_methods_lskel__attach(skel);
++ if (err)
++ goto out;
++
++ dump_bpf_map_link = bpf_link_get_from_fd(skel->links.dump_bpf_map_fd);
++ if (IS_ERR(dump_bpf_map_link)) {
++ err = PTR_ERR(dump_bpf_map_link);
++ goto out;
++ }
++
++ ringbuf_map = bpf_map_get(skel->maps.ringbuf.map_fd);
++ if (IS_ERR(ringbuf_map)) {
++ err = PTR_ERR(ringbuf_map);
++ goto out;
++ }
++
++ /* Avoid taking over stdin/stdout/stderr of init process. Zeroing out
++ * makes skel_closenz() a no-op later in iterators_bpf__destroy().
++ */
++ close_fd(skel->links.dump_bpf_map_fd);
++ skel->links.dump_bpf_map_fd = 0;
++
++ return 0;
++out:
++ free_objs_and_skel();
++ return err;
++}
++
+ #endif /* __GEN_PRELOAD_METHODS_LSKEL_SKEL_H__ */
diff --git a/tools/testing/selftests/bpf/prog_tests/test_gen_preload_methods.c b/tools/testing/selftests/bpf/prog_tests/test_gen_preload_methods.c
new file mode 100644
index 000000000000..937b3e606f53
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/test_gen_preload_methods.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
+ */
+
+#include <test_progs.h>
+
+static int duration;
+
+void test_test_gen_preload_methods(void)
+{
+ char diff_cmd[1024];
+ int err;
+
+ snprintf(diff_cmd, sizeof(diff_cmd),
+ "diff -up gen_preload_methods.lskel.h "
+ "gen_preload_methods.preload.lskel.h "
+ "| tail -n +4 | "
+ "diff -u - "
+ "<(tail -n +4 prog_tests/gen_preload_methods.expected.diff)");
+ err = system(diff_cmd);
+ if (CHECK(err, "diff",
+ "differing test output, err=%d, diff cmd:\n%s\n",
+ err, diff_cmd))
+ return;
+}
diff --git a/tools/testing/selftests/bpf/progs/gen_preload_methods.c b/tools/testing/selftests/bpf/progs/gen_preload_methods.c
new file mode 100644
index 000000000000..5b3ab27f945d
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/gen_preload_methods.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
+ */
+
+#include "vmlinux.h"
+#include <errno.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+struct {
+ __uint(type, BPF_MAP_TYPE_RINGBUF);
+ __uint(max_entries, 1 << 12);
+} ringbuf SEC(".maps");
+
+char _license[] SEC("license") = "GPL";
+
+SEC("iter/bpf_map")
+int dump_bpf_map(struct bpf_iter__bpf_map *ctx)
+{
+ return 0;
+}
--
2.32.0
More information about the Linux-security-module-archive
mailing list