This selftest contains a testcase that utilizes light skeleton eBPF loaders and exercises hornet's map validation. Signed-off-by: Blaise Boscaccy --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/hornet/Makefile | 63 ++++++++++++++++++++ tools/testing/selftests/hornet/loader.c | 21 +++++++ tools/testing/selftests/hornet/trivial.bpf.c | 33 ++++++++++ 4 files changed, 118 insertions(+) create mode 100644 tools/testing/selftests/hornet/Makefile create mode 100644 tools/testing/selftests/hornet/loader.c create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 450f13ba4cca..4e2d1cd88c82 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -44,6 +44,7 @@ TARGETS += ftrace TARGETS += futex TARGETS += gpio TARGETS += hid +TARGETS += hornet TARGETS += intel_pstate TARGETS += iommu TARGETS += ipc diff --git a/tools/testing/selftests/hornet/Makefile b/tools/testing/selftests/hornet/Makefile new file mode 100644 index 000000000000..432bce59f54e --- /dev/null +++ b/tools/testing/selftests/hornet/Makefile @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../../../build/Build.include +include ../../../scripts/Makefile.arch +include ../../../scripts/Makefile.include + +CLANG ?= clang +CFLAGS := -g -O2 -Wall +BPFTOOL ?= $(TOOLSDIR)/bpf/bpftool/bpftool +SCRIPTSDIR := $(abspath ../../../../scripts/hornet) +TOOLSDIR := $(abspath ../../..) +LIBDIR := $(TOOLSDIR)/lib +BPFDIR := $(LIBDIR)/bpf +TOOLSINCDIR := $(TOOLSDIR)/include +APIDIR := $(TOOLSINCDIR)/uapi +CERTDIR := $(abspath ../../../../certs) +PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config + +TEST_GEN_PROGS := loader +TEST_GEN_FILES := vmlinux.h loader.h trivial.bpf.o map.bin sig.bin insn.bin signed_loader.h +$(TEST_GEN_PROGS): LDLIBS += -lbpf +$(TEST_GEN_PROGS): $(TEST_GEN_FILES) + +include ../lib.mk + +BPF_CFLAGS := -target bpf \ + -D__TARGET_ARCH_$(ARCH) \ + -I/usr/include/$(shell uname -m)-linux-gnu \ + $(KHDR_INCLUDES) + +vmlinux.h: + $(BPFTOOL) btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h + +trivial.bpf.o: trivial.bpf.c vmlinux.h + $(CLANG) $(CFLAGS) $(BPF_CFLAGS) -c $< -o $@ + +loader.h: trivial.bpf.o + $(BPFTOOL) gen skeleton -S -k $(CERTDIR)/signing_key.pem -i $(CERTDIR)/signing_key.x509 \ + -L $< name trivial > $@ + +insn.bin: loader.h + $(SCRIPTSDIR)/extract-insn.sh $< > $@ + +map.bin: loader.h + $(SCRIPTSDIR)/extract-map.sh $< > $@ + +$(OUTPUT)/gen_sig: ../../../../scripts/hornet/gen_sig.c + $(call msg,GEN_SIG,,$@) + $(Q)$(CC) $(shell $(PKG_CONFIG) --cflags libcrypto 2> /dev/null) \ + $< -o $@ \ + $(shell $(PKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) + +sig.bin: insn.bin map.bin $(OUTPUT)/gen_sig + $(OUTPUT)/gen_sig --key $(CERTDIR)/signing_key.pem --cert $(CERTDIR)/signing_key.x509 \ + --data insn.bin --add map.bin:0 --out sig.bin + +signed_loader.h: sig.bin + $(SCRIPTSDIR)/write-sig.sh loader.h sig.bin > $@ + +loader: loader.c signed_loader.h + $(CC) $(CFLAGS) -I$(LIBDIR) -I$(APIDIR) $< -o $@ -lbpf + + +EXTRA_CLEAN = $(OUTPUT)/gen_sig diff --git a/tools/testing/selftests/hornet/loader.c b/tools/testing/selftests/hornet/loader.c new file mode 100644 index 000000000000..f27580c7262b --- /dev/null +++ b/tools/testing/selftests/hornet/loader.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +#include +#include +#include +#include +#include +#include +#include "signed_loader.h" + +int main(int argc, char **argv) +{ + struct trivial *skel; + + skel = trivial__open_and_load(); + if (!skel) + return -1; + + trivial__destroy(skel); + return 0; +} diff --git a/tools/testing/selftests/hornet/trivial.bpf.c b/tools/testing/selftests/hornet/trivial.bpf.c new file mode 100644 index 000000000000..d38c5b53ff93 --- /dev/null +++ b/tools/testing/selftests/hornet/trivial.bpf.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +#include "vmlinux.h" + +#include +#include +#include + +char LICENSE[] SEC("license") = "Dual BSD/GPL"; + +int monitored_pid = 0; + +SEC("tracepoint/syscalls/sys_enter_unlinkat") +int handle_enter_unlink(struct trace_event_raw_sys_enter *ctx) +{ + char filename[128] = { 0 }; + struct task_struct *task; + unsigned long start_time = 0; + int pid = bpf_get_current_pid_tgid() >> 32; + char *pathname_ptr = (char *) BPF_CORE_READ(ctx, args[1]); + + bpf_probe_read_str(filename, sizeof(filename), pathname_ptr); + task = (struct task_struct *)bpf_get_current_task(); + start_time = BPF_CORE_READ(task, start_time); + + bpf_printk("BPF triggered unlinkat by PID: %d, start_time %ld. pathname = %s", + pid, start_time, filename); + + if (monitored_pid == pid) + bpf_printk("target pid found"); + + return 0; +} -- 2.52.0