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

selftests/bpf: Test bpf_core_types_are_compat() functionality.

Add several tests to check bpf_core_types_are_compat() functionality:
- candidate type name exists and types match
- candidate type name exists but types don't match
- nested func protos at kernel recursion limit
- nested func protos above kernel recursion limit. Such bpf prog
is rejected during the load.

Signed-off-by: Matteo Croce <mcroce@microsoft.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20220204005519.60361-3-mcroce@linux.microsoft.com

authored by

Matteo Croce and committed by
Alexei Starovoitov
976a38e0 e70e13e7

+74 -2
+1 -1
tools/testing/selftests/bpf/Makefile
··· 330 330 331 331 LSKELS := kfunc_call_test.c fentry_test.c fexit_test.c fexit_sleep.c \ 332 332 test_ringbuf.c atomics.c trace_printk.c trace_vprintk.c \ 333 - map_ptr_kern.c core_kern.c 333 + map_ptr_kern.c core_kern.c core_kern_overflow.c 334 334 # Generate both light skeleton and libbpf skeleton for these 335 335 LSKELS_EXTRA := test_ksyms_module.c test_ksyms_weak.c kfunc_call_test_subprog.c 336 336 SKEL_BLACKLIST += $$(LSKELS)
+7
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
··· 13 13 #define CREATE_TRACE_POINTS 14 14 #include "bpf_testmod-events.h" 15 15 16 + typedef int (*func_proto_typedef)(long); 17 + typedef int (*func_proto_typedef_nested1)(func_proto_typedef); 18 + typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1); 19 + 16 20 DEFINE_PER_CPU(int, bpf_testmod_ksym_percpu) = 123; 17 21 18 22 noinline void ··· 35 31 36 32 noinline int 37 33 bpf_testmod_test_btf_type_tag_user_1(struct bpf_testmod_btf_type_tag_1 __user *arg) { 34 + BTF_TYPE_EMIT(func_proto_typedef); 35 + BTF_TYPE_EMIT(func_proto_typedef_nested1); 36 + BTF_TYPE_EMIT(func_proto_typedef_nested2); 38 37 return arg->a; 39 38 } 40 39
+15 -1
tools/testing/selftests/bpf/prog_tests/core_kern.c
··· 7 7 void test_core_kern_lskel(void) 8 8 { 9 9 struct core_kern_lskel *skel; 10 + int link_fd; 10 11 11 12 skel = core_kern_lskel__open_and_load(); 12 - ASSERT_OK_PTR(skel, "open_and_load"); 13 + if (!ASSERT_OK_PTR(skel, "open_and_load")) 14 + return; 15 + 16 + link_fd = core_kern_lskel__core_relo_proto__attach(skel); 17 + if (!ASSERT_GT(link_fd, 0, "attach(core_relo_proto)")) 18 + goto cleanup; 19 + 20 + /* trigger tracepoints */ 21 + usleep(1); 22 + ASSERT_TRUE(skel->bss->proto_out[0], "bpf_core_type_exists"); 23 + ASSERT_FALSE(skel->bss->proto_out[1], "!bpf_core_type_exists"); 24 + ASSERT_TRUE(skel->bss->proto_out[2], "bpf_core_type_exists. nested"); 25 + 26 + cleanup: 13 27 core_kern_lskel__destroy(skel); 14 28 }
+13
tools/testing/selftests/bpf/prog_tests/core_kern_overflow.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "test_progs.h" 4 + #include "core_kern_overflow.lskel.h" 5 + 6 + void test_core_kern_overflow_lskel(void) 7 + { 8 + struct core_kern_overflow_lskel *skel; 9 + 10 + skel = core_kern_overflow_lskel__open_and_load(); 11 + if (!ASSERT_NULL(skel, "open_and_load")) 12 + core_kern_overflow_lskel__destroy(skel); 13 + }
+16
tools/testing/selftests/bpf/progs/core_kern.c
··· 101 101 return 0; 102 102 } 103 103 104 + typedef int (*func_proto_typedef___match)(long); 105 + typedef int (*func_proto_typedef___doesnt_match)(char *); 106 + typedef int (*func_proto_typedef_nested1)(func_proto_typedef___match); 107 + 108 + int proto_out[3]; 109 + 110 + SEC("raw_tracepoint/sys_enter") 111 + int core_relo_proto(void *ctx) 112 + { 113 + proto_out[0] = bpf_core_type_exists(func_proto_typedef___match); 114 + proto_out[1] = bpf_core_type_exists(func_proto_typedef___doesnt_match); 115 + proto_out[2] = bpf_core_type_exists(func_proto_typedef_nested1); 116 + 117 + return 0; 118 + } 119 + 104 120 char LICENSE[] SEC("license") = "GPL";
+22
tools/testing/selftests/bpf/progs/core_kern_overflow.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "vmlinux.h" 3 + 4 + #include <bpf/bpf_helpers.h> 5 + #include <bpf/bpf_tracing.h> 6 + #include <bpf/bpf_core_read.h> 7 + 8 + typedef int (*func_proto_typedef)(long); 9 + typedef int (*func_proto_typedef_nested1)(func_proto_typedef); 10 + typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1); 11 + 12 + int proto_out; 13 + 14 + SEC("raw_tracepoint/sys_enter") 15 + int core_relo_proto(void *ctx) 16 + { 17 + proto_out = bpf_core_type_exists(func_proto_typedef_nested2); 18 + 19 + return 0; 20 + } 21 + 22 + char LICENSE[] SEC("license") = "GPL";