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

selftests/bpf: Verify calling core kfuncs from BPF_PROG_TYPE_SYCALL

Now that we can call some kfuncs from BPF_PROG_TYPE_SYSCALL progs, let's
add some selftests that verify as much. As a bonus, let's also verify
that we can't call the progs from raw tracepoints. Do do this, we add a
new selftest suite called verifier_kfunc_prog_types.

Signed-off-by: David Vernet <void@manifault.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/bpf/20240405143041.632519-3-void@manifault.com

authored by

David Vernet and committed by
Andrii Nakryiko
1bc724af a8e03b6b

+135 -2
+11
tools/testing/selftests/bpf/prog_tests/verifier_kfunc_prog_types.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include <test_progs.h> 5 + 6 + #include "verifier_kfunc_prog_types.skel.h" 7 + 8 + void test_verifier_kfunc_prog_types(void) 9 + { 10 + RUN_TESTS(verifier_kfunc_prog_types); 11 + }
+1 -1
tools/testing/selftests/bpf/progs/cgrp_kfunc_common.h
··· 13 13 struct cgroup __kptr * cgrp; 14 14 }; 15 15 16 - struct hash_map { 16 + struct { 17 17 __uint(type, BPF_MAP_TYPE_HASH); 18 18 __type(key, int); 19 19 __type(value, struct __cgrps_kfunc_map_value);
+1 -1
tools/testing/selftests/bpf/progs/task_kfunc_common.h
··· 13 13 struct task_struct __kptr * task; 14 14 }; 15 15 16 - struct hash_map { 16 + struct { 17 17 __uint(type, BPF_MAP_TYPE_HASH); 18 18 __type(key, int); 19 19 __type(value, struct __tasks_kfunc_map_value);
+122
tools/testing/selftests/bpf/progs/verifier_kfunc_prog_types.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include <vmlinux.h> 5 + #include <bpf/bpf_tracing.h> 6 + #include <bpf/bpf_helpers.h> 7 + 8 + #include "bpf_misc.h" 9 + #include "cgrp_kfunc_common.h" 10 + #include "cpumask_common.h" 11 + #include "task_kfunc_common.h" 12 + 13 + char _license[] SEC("license") = "GPL"; 14 + 15 + /*************** 16 + * Task kfuncs * 17 + ***************/ 18 + 19 + static void task_kfunc_load_test(void) 20 + { 21 + struct task_struct *current, *ref_1, *ref_2; 22 + 23 + current = bpf_get_current_task_btf(); 24 + ref_1 = bpf_task_from_pid(current->pid); 25 + if (!ref_1) 26 + return; 27 + 28 + ref_2 = bpf_task_acquire(ref_1); 29 + if (ref_2) 30 + bpf_task_release(ref_2); 31 + bpf_task_release(ref_1); 32 + } 33 + 34 + SEC("raw_tp") 35 + __failure __msg("calling kernel function") 36 + int BPF_PROG(task_kfunc_raw_tp) 37 + { 38 + task_kfunc_load_test(); 39 + return 0; 40 + } 41 + 42 + SEC("syscall") 43 + __success 44 + int BPF_PROG(task_kfunc_syscall) 45 + { 46 + task_kfunc_load_test(); 47 + return 0; 48 + } 49 + 50 + /***************** 51 + * cgroup kfuncs * 52 + *****************/ 53 + 54 + static void cgrp_kfunc_load_test(void) 55 + { 56 + struct cgroup *cgrp, *ref; 57 + 58 + cgrp = bpf_cgroup_from_id(0); 59 + if (!cgrp) 60 + return; 61 + 62 + ref = bpf_cgroup_acquire(cgrp); 63 + if (!ref) { 64 + bpf_cgroup_release(cgrp); 65 + return; 66 + } 67 + 68 + bpf_cgroup_release(ref); 69 + bpf_cgroup_release(cgrp); 70 + } 71 + 72 + SEC("raw_tp") 73 + __failure __msg("calling kernel function") 74 + int BPF_PROG(cgrp_kfunc_raw_tp) 75 + { 76 + cgrp_kfunc_load_test(); 77 + return 0; 78 + } 79 + 80 + SEC("syscall") 81 + __success 82 + int BPF_PROG(cgrp_kfunc_syscall) 83 + { 84 + cgrp_kfunc_load_test(); 85 + return 0; 86 + } 87 + 88 + /****************** 89 + * cpumask kfuncs * 90 + ******************/ 91 + 92 + static void cpumask_kfunc_load_test(void) 93 + { 94 + struct bpf_cpumask *alloc, *ref; 95 + 96 + alloc = bpf_cpumask_create(); 97 + if (!alloc) 98 + return; 99 + 100 + ref = bpf_cpumask_acquire(alloc); 101 + bpf_cpumask_set_cpu(0, alloc); 102 + bpf_cpumask_test_cpu(0, (const struct cpumask *)ref); 103 + 104 + bpf_cpumask_release(ref); 105 + bpf_cpumask_release(alloc); 106 + } 107 + 108 + SEC("raw_tp") 109 + __failure __msg("calling kernel function") 110 + int BPF_PROG(cpumask_kfunc_raw_tp) 111 + { 112 + cpumask_kfunc_load_test(); 113 + return 0; 114 + } 115 + 116 + SEC("syscall") 117 + __success 118 + int BPF_PROG(cpumask_kfunc_syscall) 119 + { 120 + cpumask_kfunc_load_test(); 121 + return 0; 122 + }