Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Enable signature verification for some lskel tests

The test harness uses the verify_sig_setup.sh to generate the required
key material for program signing.

Generate key material for signing LSKEL some lskel programs and use
xxd to convert the verification certificate into a C header file.

Finally, update the main test runner to load this
certificate into the session keyring via the add_key() syscall before
executing any tests. Use the session keyring in the tests with signed
programs.

Signed-off-by: KP Singh <kpsingh@kernel.org>
Link: https://lore.kernel.org/r/20250921160120.9711-6-kpsingh@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

KP Singh and committed by
Alexei Starovoitov
b720903e 40863f4d

+89 -14
+1
tools/testing/selftests/bpf/.gitignore
··· 44 44 xdp_synproxy 45 45 xdp_hw_metadata 46 46 xdp_features 47 + verification_cert.h
+31 -4
tools/testing/selftests/bpf/Makefile
··· 496 496 test_subskeleton.skel.h test_subskeleton_lib.skel.h \ 497 497 test_usdt.skel.h 498 498 499 - LSKELS := fentry_test.c fexit_test.c fexit_sleep.c atomics.c \ 500 - trace_printk.c trace_vprintk.c map_ptr_kern.c \ 499 + LSKELS := fexit_sleep.c trace_printk.c trace_vprintk.c map_ptr_kern.c \ 501 500 core_kern.c core_kern_overflow.c test_ringbuf.c \ 502 501 test_ringbuf_n.c test_ringbuf_map_key.c test_ringbuf_write.c 502 + 503 + LSKELS_SIGNED := fentry_test.c fexit_test.c atomics.c 503 504 504 505 # Generate both light skeleton and libbpf skeleton for these 505 506 LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test.c \ 506 507 kfunc_call_test_subprog.c 507 - SKEL_BLACKLIST += $$(LSKELS) 508 + SKEL_BLACKLIST += $$(LSKELS) $$(LSKELS_SIGNED) 508 509 509 510 test_static_linked.skel.h-deps := test_static_linked1.bpf.o test_static_linked2.bpf.o 510 511 linked_funcs.skel.h-deps := linked_funcs1.bpf.o linked_funcs2.bpf.o ··· 536 535 # $2 - test runner extra "flavor" (e.g., no_alu32, cpuv4, bpf_gcc, etc) 537 536 define DEFINE_TEST_RUNNER 538 537 538 + LSKEL_SIGN := -S -k $(PRIVATE_KEY) -i $(VERIFICATION_CERT) 539 539 TRUNNER_OUTPUT := $(OUTPUT)$(if $2,/)$2 540 540 TRUNNER_BINARY := $1$(if $2,-)$2 541 541 TRUNNER_TEST_OBJS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.test.o, \ ··· 552 550 $$(TRUNNER_BPF_SRCS))) 553 551 TRUNNER_BPF_LSKELS := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.lskel.h, $$(LSKELS) $$(LSKELS_EXTRA)) 554 552 TRUNNER_BPF_SKELS_LINKED := $$(addprefix $$(TRUNNER_OUTPUT)/,$(LINKED_SKELS)) 553 + TRUNNER_BPF_LSKELS_SIGNED := $$(patsubst %.c,$$(TRUNNER_OUTPUT)/%.lskel.h, $$(LSKELS_SIGNED)) 555 554 TEST_GEN_FILES += $$(TRUNNER_BPF_OBJS) 556 555 557 556 # Evaluate rules now with extra TRUNNER_XXX variables above already defined ··· 607 604 $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir $$(<:.bpf.o=_lskel)) > $$@ 608 605 $(Q)rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 609 606 607 + $(TRUNNER_BPF_LSKELS_SIGNED): %.lskel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT) 608 + $$(call msg,GEN-SKEL,$(TRUNNER_BINARY) (signed),$$@) 609 + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$< 610 + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o) 611 + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) 612 + $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 613 + $(Q)$$(BPFTOOL) gen skeleton $(LSKEL_SIGN) $$(<:.o=.llinked3.o) name $$(notdir $$(<:.bpf.o=_lskel)) > $$@ 614 + $(Q)rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 615 + 610 616 $(LINKED_BPF_OBJS): %: $(TRUNNER_OUTPUT)/% 611 617 612 618 # .SECONDEXPANSION here allows to correctly expand %-deps variables as prerequisites ··· 665 653 $(TRUNNER_EXTRA_HDRS) \ 666 654 $(TRUNNER_BPF_SKELS) \ 667 655 $(TRUNNER_BPF_LSKELS) \ 656 + $(TRUNNER_BPF_LSKELS_SIGNED) \ 668 657 $(TRUNNER_BPF_SKELS_LINKED) \ 669 658 $$(BPFOBJ) | $(TRUNNER_OUTPUT) 670 659 ··· 680 667 $(TRUNNER_EXTRA_OBJS): $(TRUNNER_OUTPUT)/%.o: \ 681 668 %.c \ 682 669 $(TRUNNER_EXTRA_HDRS) \ 670 + $(VERIFY_SIG_HDR) \ 683 671 $(TRUNNER_TESTS_HDR) \ 684 672 $$(BPFOBJ) | $(TRUNNER_OUTPUT) 685 673 $$(call msg,EXT-OBJ,$(TRUNNER_BINARY),$$@) ··· 711 697 712 698 endef 713 699 700 + VERIFY_SIG_SETUP := $(CURDIR)/verify_sig_setup.sh 701 + VERIFY_SIG_HDR := verification_cert.h 702 + VERIFICATION_CERT := $(BUILD_DIR)/signing_key.der 703 + PRIVATE_KEY := $(BUILD_DIR)/signing_key.pem 704 + 705 + $(VERIFICATION_CERT) $(PRIVATE_KEY): $(VERIFY_SIG_SETUP) 706 + $(Q)mkdir -p $(BUILD_DIR) 707 + $(Q)$(VERIFY_SIG_SETUP) genkey $(BUILD_DIR) 708 + 709 + $(VERIFY_SIG_HDR): $(VERIFICATION_CERT) 710 + $(Q)xxd -i -n test_progs_verification_cert $< > $@ 711 + 714 712 # Define test_progs test runner. 715 713 TRUNNER_TESTS_DIR := prog_tests 716 714 TRUNNER_BPF_PROGS_DIR := progs ··· 742 716 disasm.c \ 743 717 disasm_helpers.c \ 744 718 json_writer.c \ 719 + $(VERIFY_SIG_HDR) \ 745 720 flow_dissector_load.h \ 746 721 ip_check_defrag_frags.h 747 722 TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read \ ··· 752 725 $(OUTPUT)/uprobe_multi \ 753 726 $(TEST_KMOD_TARGETS) \ 754 727 ima_setup.sh \ 755 - verify_sig_setup.sh \ 728 + $(VERIFY_SIG_SETUP) \ 756 729 $(wildcard progs/btf_dump_test_case_*.c) \ 757 730 $(wildcard progs/*.bpf.o) 758 731 TRUNNER_BPF_BUILD_RULE := CLANG_BPF_BUILD_RULE
+8 -2
tools/testing/selftests/bpf/prog_tests/atomics.c
··· 165 165 void test_atomics(void) 166 166 { 167 167 struct atomics_lskel *skel; 168 + int err; 168 169 169 - skel = atomics_lskel__open_and_load(); 170 - if (!ASSERT_OK_PTR(skel, "atomics skeleton load")) 170 + skel = atomics_lskel__open(); 171 + if (!ASSERT_OK_PTR(skel, "atomics skeleton open")) 171 172 return; 173 + 174 + skel->keyring_id = KEY_SPEC_SESSION_KEYRING; 175 + err = atomics_lskel__load(skel); 176 + if (!ASSERT_OK(err, "atomics skeleton load")) 177 + goto cleanup; 172 178 173 179 if (skel->data->skip_tests) { 174 180 printf("%s:SKIP:no ENABLE_ATOMICS_TESTS (missing Clang BPF atomics support)",
+13 -2
tools/testing/selftests/bpf/prog_tests/fentry_fexit.c
··· 12 12 int err, prog_fd, i; 13 13 LIBBPF_OPTS(bpf_test_run_opts, topts); 14 14 15 - fentry_skel = fentry_test_lskel__open_and_load(); 15 + fentry_skel = fentry_test_lskel__open(); 16 16 if (!ASSERT_OK_PTR(fentry_skel, "fentry_skel_load")) 17 17 goto close_prog; 18 - fexit_skel = fexit_test_lskel__open_and_load(); 18 + 19 + fentry_skel->keyring_id = KEY_SPEC_SESSION_KEYRING; 20 + err = fentry_test_lskel__load(fentry_skel); 21 + if (!ASSERT_OK(err, "fentry_skel_load")) 22 + goto close_prog; 23 + 24 + fexit_skel = fexit_test_lskel__open(); 19 25 if (!ASSERT_OK_PTR(fexit_skel, "fexit_skel_load")) 26 + goto close_prog; 27 + 28 + fexit_skel->keyring_id = KEY_SPEC_SESSION_KEYRING; 29 + err = fexit_test_lskel__load(fexit_skel); 30 + if (!ASSERT_OK(err, "fexit_skel_load")) 20 31 goto close_prog; 21 32 22 33 err = fentry_test_lskel__attach(fentry_skel);
+7 -2
tools/testing/selftests/bpf/prog_tests/fentry_test.c
··· 43 43 struct fentry_test_lskel *fentry_skel = NULL; 44 44 int err; 45 45 46 - fentry_skel = fentry_test_lskel__open_and_load(); 47 - if (!ASSERT_OK_PTR(fentry_skel, "fentry_skel_load")) 46 + fentry_skel = fentry_test_lskel__open(); 47 + if (!ASSERT_OK_PTR(fentry_skel, "fentry_skel_open")) 48 + goto cleanup; 49 + 50 + fentry_skel->keyring_id = KEY_SPEC_SESSION_KEYRING; 51 + err = fentry_test_lskel__load(fentry_skel); 52 + if (!ASSERT_OK(err, "fentry_skel_load")) 48 53 goto cleanup; 49 54 50 55 err = fentry_test_common(fentry_skel);
+7 -2
tools/testing/selftests/bpf/prog_tests/fexit_test.c
··· 43 43 struct fexit_test_lskel *fexit_skel = NULL; 44 44 int err; 45 45 46 - fexit_skel = fexit_test_lskel__open_and_load(); 47 - if (!ASSERT_OK_PTR(fexit_skel, "fexit_skel_load")) 46 + fexit_skel = fexit_test_lskel__open(); 47 + if (!ASSERT_OK_PTR(fexit_skel, "fexit_skel_open")) 48 + goto cleanup; 49 + 50 + fexit_skel->keyring_id = KEY_SPEC_SESSION_KEYRING; 51 + err = fexit_test_lskel__load(fexit_skel); 52 + if (!ASSERT_OK(err, "fexit_skel_load")) 48 53 goto cleanup; 49 54 50 55 err = fexit_test_common(fexit_skel);
+13
tools/testing/selftests/bpf/test_progs.c
··· 14 14 #include <netinet/in.h> 15 15 #include <sys/select.h> 16 16 #include <sys/socket.h> 17 + #include <linux/keyctl.h> 17 18 #include <sys/un.h> 18 19 #include <bpf/btf.h> 19 20 #include <time.h> 20 21 #include "json_writer.h" 21 22 22 23 #include "network_helpers.h" 24 + #include "verification_cert.h" 23 25 24 26 /* backtrace() and backtrace_symbols_fd() are glibc specific, 25 27 * use header file when glibc is available and provide stub ··· 1930 1928 } 1931 1929 } 1932 1930 1931 + static __u32 register_session_key(const char *key_data, size_t key_data_size) 1932 + { 1933 + return syscall(__NR_add_key, "asymmetric", "libbpf_session_key", 1934 + (const void *)key_data, key_data_size, 1935 + KEY_SPEC_SESSION_KEYRING); 1936 + } 1937 + 1933 1938 int main(int argc, char **argv) 1934 1939 { 1935 1940 static const struct argp argp = { ··· 1970 1961 /* Use libbpf 1.0 API mode */ 1971 1962 libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 1972 1963 libbpf_set_print(libbpf_print_fn); 1964 + err = register_session_key((const char *)test_progs_verification_cert, 1965 + test_progs_verification_cert_len); 1966 + if (err < 0) 1967 + return err; 1973 1968 1974 1969 traffic_monitor_set_print(traffic_monitor_print_fn); 1975 1970
+9 -2
tools/testing/selftests/bpf/verify_sig_setup.sh
··· 32 32 exit 1 33 33 } 34 34 35 - setup() 35 + genkey() 36 36 { 37 37 local tmp_dir="$1" 38 38 ··· 45 45 46 46 openssl x509 -in ${tmp_dir}/signing_key.pem -out \ 47 47 ${tmp_dir}/signing_key.der -outform der 48 + } 48 49 50 + setup() 51 + { 52 + local tmp_dir="$1" 53 + 54 + genkey "${tmp_dir}" 49 55 key_id=$(cat ${tmp_dir}/signing_key.der | keyctl padd asymmetric ebpf_testing_key @s) 50 - 51 56 keyring_id=$(keyctl newring ebpf_testing_keyring @s) 52 57 keyctl link $key_id $keyring_id 53 58 } ··· 110 105 111 106 if [[ "${action}" == "setup" ]]; then 112 107 setup "${tmp_dir}" 108 + elif [[ "${action}" == "genkey" ]]; then 109 + genkey "${tmp_dir}" 113 110 elif [[ "${action}" == "cleanup" ]]; then 114 111 cleanup "${tmp_dir}" 115 112 elif [[ "${action}" == "fsverity-create-sign" ]]; then