1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
5 #include <bpf/bpf_tracing.h>
6 #include <bpf/bpf_helpers.h>
9 #include "cpumask_common.h"
11 char _license[] SEC("license") = "GPL";
13 /* Prototype for all of the program trace events below:
15 * TRACE_EVENT(task_newtask,
16 * TP_PROTO(struct task_struct *p, u64 clone_flags)
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)
23 struct bpf_cpumask *cpumask;
25 cpumask = create_cpumask();
28 /* cpumask is never released. */
32 SEC("tp_btf/task_newtask")
33 __failure __msg("NULL pointer passed to trusted arg0")
34 int BPF_PROG(test_alloc_double_release, struct task_struct *task, u64 clone_flags)
36 struct bpf_cpumask *cpumask;
38 cpumask = create_cpumask();
40 /* cpumask is released twice. */
41 bpf_cpumask_release(cpumask);
42 bpf_cpumask_release(cpumask);
47 SEC("tp_btf/task_newtask")
48 __failure __msg("must be referenced")
49 int BPF_PROG(test_acquire_wrong_cpumask, struct task_struct *task, u64 clone_flags)
51 struct bpf_cpumask *cpumask;
53 /* Can't acquire a non-struct bpf_cpumask. */
54 cpumask = bpf_cpumask_acquire((struct bpf_cpumask *)task->cpus_ptr);
60 SEC("tp_btf/task_newtask")
61 __failure __msg("bpf_cpumask_set_cpu args#1 expected pointer to STRUCT bpf_cpumask")
62 int BPF_PROG(test_mutate_cpumask, struct task_struct *task, u64 clone_flags)
64 struct bpf_cpumask *cpumask;
66 /* Can't set the CPU of a non-struct bpf_cpumask. */
67 bpf_cpumask_set_cpu(0, (struct bpf_cpumask *)task->cpus_ptr);
73 SEC("tp_btf/task_newtask")
74 __failure __msg("Unreleased reference")
75 int BPF_PROG(test_insert_remove_no_release, struct task_struct *task, u64 clone_flags)
77 struct bpf_cpumask *cpumask;
78 struct __cpumask_map_value *v;
80 cpumask = create_cpumask();
84 if (cpumask_map_insert(cpumask))
87 v = cpumask_map_value_lookup();
91 cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
93 /* cpumask is never released. */
97 SEC("tp_btf/task_newtask")
98 __failure __msg("NULL pointer passed to trusted arg0")
99 int BPF_PROG(test_cpumask_null, struct task_struct *task, u64 clone_flags)
101 /* NULL passed to KF_TRUSTED_ARGS kfunc. */
102 bpf_cpumask_empty(NULL);
107 SEC("tp_btf/task_newtask")
108 __failure __msg("R2 must be a rcu pointer")
109 int BPF_PROG(test_global_mask_out_of_rcu, struct task_struct *task, u64 clone_flags)
111 struct bpf_cpumask *local, *prev;
113 local = create_cpumask();
117 prev = bpf_kptr_xchg(&global_mask, local);
119 bpf_cpumask_release(prev);
128 bpf_rcu_read_unlock();
132 bpf_rcu_read_unlock();
134 /* RCU region is exited before calling KF_RCU kfunc. */
136 bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
141 SEC("tp_btf/task_newtask")
142 __failure __msg("NULL pointer passed to trusted arg1")
143 int BPF_PROG(test_global_mask_no_null_check, struct task_struct *task, u64 clone_flags)
145 struct bpf_cpumask *local, *prev;
147 local = create_cpumask();
151 prev = bpf_kptr_xchg(&global_mask, local);
153 bpf_cpumask_release(prev);
161 /* No NULL check is performed on global cpumask kptr. */
162 bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
164 bpf_rcu_read_unlock();
169 SEC("tp_btf/task_newtask")
170 __failure __msg("Possibly NULL pointer passed to helper arg2")
171 int BPF_PROG(test_global_mask_rcu_no_null_check, struct task_struct *task, u64 clone_flags)
173 struct bpf_cpumask *prev, *curr;
175 curr = bpf_cpumask_create();
179 prev = bpf_kptr_xchg(&global_mask, curr);
181 bpf_cpumask_release(prev);
185 /* PTR_TO_BTF_ID | PTR_MAYBE_NULL | MEM_RCU passed to bpf_kptr_xchg() */
186 prev = bpf_kptr_xchg(&global_mask, curr);
187 bpf_rcu_read_unlock();
189 bpf_cpumask_release(prev);