1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 4 #include <vmlinux.h> 5 #include <bpf/bpf_tracing.h> 6 #include <bpf/bpf_helpers.h> 7 #include "bpf_misc.h" 8 9 #include "cpumask_common.h" 10 11 char _license[] SEC("license") = "GPL"; 12 13 /* Prototype for all of the program trace events below: 14 * 15 * TRACE_EVENT(task_newtask, 16 * TP_PROTO(struct task_struct *p, u64 clone_flags) 17 */ 18 19 SEC("tp_btf/task_newtask") 20 __failure __msg("Unreleased reference") 21 int BPF_PROG(test_alloc_no_release, struct task_struct *task, u64 clone_flags) 22 { 23 struct bpf_cpumask *cpumask; 24 25 cpumask = create_cpumask(); 26 27 /* cpumask is never released. */ 28 return 0; 29 } 30 31 SEC("tp_btf/task_newtask") 32 __failure __msg("NULL pointer passed to trusted arg0") 33 int BPF_PROG(test_alloc_double_release, struct task_struct *task, u64 clone_flags) 34 { 35 struct bpf_cpumask *cpumask; 36 37 cpumask = create_cpumask(); 38 39 /* cpumask is released twice. */ 40 bpf_cpumask_release(cpumask); 41 bpf_cpumask_release(cpumask); 42 43 return 0; 44 } 45 46 SEC("tp_btf/task_newtask") 47 __failure __msg("bpf_cpumask_acquire args#0 expected pointer to STRUCT bpf_cpumask") 48 int BPF_PROG(test_acquire_wrong_cpumask, struct task_struct *task, u64 clone_flags) 49 { 50 struct bpf_cpumask *cpumask; 51 52 /* Can't acquire a non-struct bpf_cpumask. */ 53 cpumask = bpf_cpumask_acquire((struct bpf_cpumask *)task->cpus_ptr); 54 55 return 0; 56 } 57 58 SEC("tp_btf/task_newtask") 59 __failure __msg("bpf_cpumask_set_cpu args#1 expected pointer to STRUCT bpf_cpumask") 60 int BPF_PROG(test_mutate_cpumask, struct task_struct *task, u64 clone_flags) 61 { 62 struct bpf_cpumask *cpumask; 63 64 /* Can't set the CPU of a non-struct bpf_cpumask. */ 65 bpf_cpumask_set_cpu(0, (struct bpf_cpumask *)task->cpus_ptr); 66 67 return 0; 68 } 69 70 SEC("tp_btf/task_newtask") 71 __failure __msg("Unreleased reference") 72 int BPF_PROG(test_insert_remove_no_release, struct task_struct *task, u64 clone_flags) 73 { 74 struct bpf_cpumask *cpumask; 75 struct __cpumask_map_value *v; 76 77 cpumask = create_cpumask(); 78 if (!cpumask) 79 return 0; 80 81 if (cpumask_map_insert(cpumask)) 82 return 0; 83 84 v = cpumask_map_value_lookup(); 85 if (!v) 86 return 0; 87 88 cpumask = bpf_kptr_xchg(&v->cpumask, NULL); 89 90 /* cpumask is never released. */ 91 return 0; 92 } 93 94 SEC("tp_btf/task_newtask") 95 __failure __msg("Unreleased reference") 96 int BPF_PROG(test_kptr_get_no_release, struct task_struct *task, u64 clone_flags) 97 { 98 struct bpf_cpumask *cpumask; 99 struct __cpumask_map_value *v; 100 101 cpumask = create_cpumask(); 102 if (!cpumask) 103 return 0; 104 105 if (cpumask_map_insert(cpumask)) 106 return 0; 107 108 v = cpumask_map_value_lookup(); 109 if (!v) 110 return 0; 111 112 cpumask = bpf_cpumask_kptr_get(&v->cpumask); 113 114 /* cpumask is never released. */ 115 return 0; 116 } 117 118 SEC("tp_btf/task_newtask") 119 __failure __msg("NULL pointer passed to trusted arg0") 120 int BPF_PROG(test_cpumask_null, struct task_struct *task, u64 clone_flags) 121 { 122 /* NULL passed to KF_TRUSTED_ARGS kfunc. */ 123 bpf_cpumask_empty(NULL); 124 125 return 0; 126 } 127