Linux Audio

Check our new training course

Loading...
v6.13.7
  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
 11char _license[] SEC("license") = "GPL";
 12
 13struct kptr_nested_array_2 {
 14	struct bpf_cpumask __kptr * mask;
 15};
 16
 17struct kptr_nested_array_1 {
 18	/* Make btf_parse_fields() in map_create() return -E2BIG */
 19	struct kptr_nested_array_2 d_2[CPUMASK_KPTR_FIELDS_MAX + 1];
 20};
 21
 22struct kptr_nested_array {
 23	struct kptr_nested_array_1 d_1;
 24};
 25
 26private(MASK_NESTED) static struct kptr_nested_array global_mask_nested_arr;
 27
 28/* Prototype for all of the program trace events below:
 29 *
 30 * TRACE_EVENT(task_newtask,
 31 *         TP_PROTO(struct task_struct *p, u64 clone_flags)
 32 */
 33
 34SEC("tp_btf/task_newtask")
 35__failure __msg("Unreleased reference")
 36int BPF_PROG(test_alloc_no_release, struct task_struct *task, u64 clone_flags)
 37{
 38	struct bpf_cpumask *cpumask;
 39
 40	cpumask = create_cpumask();
 41	__sink(cpumask);
 42
 43	/* cpumask is never released. */
 44	return 0;
 45}
 46
 47SEC("tp_btf/task_newtask")
 48__failure __msg("NULL pointer passed to trusted arg0")
 49int BPF_PROG(test_alloc_double_release, struct task_struct *task, u64 clone_flags)
 50{
 51	struct bpf_cpumask *cpumask;
 52
 53	cpumask = create_cpumask();
 54
 55	/* cpumask is released twice. */
 56	bpf_cpumask_release(cpumask);
 57	bpf_cpumask_release(cpumask);
 58
 59	return 0;
 60}
 61
 62SEC("tp_btf/task_newtask")
 63__failure __msg("must be referenced")
 64int BPF_PROG(test_acquire_wrong_cpumask, struct task_struct *task, u64 clone_flags)
 65{
 66	struct bpf_cpumask *cpumask;
 67
 68	/* Can't acquire a non-struct bpf_cpumask. */
 69	cpumask = bpf_cpumask_acquire((struct bpf_cpumask *)task->cpus_ptr);
 70	__sink(cpumask);
 71
 72	return 0;
 73}
 74
 75SEC("tp_btf/task_newtask")
 76__failure __msg("bpf_cpumask_set_cpu args#1 expected pointer to STRUCT bpf_cpumask")
 77int BPF_PROG(test_mutate_cpumask, struct task_struct *task, u64 clone_flags)
 78{
 
 
 79	/* Can't set the CPU of a non-struct bpf_cpumask. */
 80	bpf_cpumask_set_cpu(0, (struct bpf_cpumask *)task->cpus_ptr);
 
 81
 82	return 0;
 83}
 84
 85SEC("tp_btf/task_newtask")
 86__failure __msg("Unreleased reference")
 87int BPF_PROG(test_insert_remove_no_release, struct task_struct *task, u64 clone_flags)
 88{
 89	struct bpf_cpumask *cpumask;
 90	struct __cpumask_map_value *v;
 91
 92	cpumask = create_cpumask();
 93	if (!cpumask)
 94		return 0;
 95
 96	if (cpumask_map_insert(cpumask))
 97		return 0;
 98
 99	v = cpumask_map_value_lookup();
100	if (!v)
101		return 0;
102
103	cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
104
105	/* cpumask is never released. */
106	return 0;
107}
108
109SEC("tp_btf/task_newtask")
110__failure __msg("NULL pointer passed to trusted arg0")
111int BPF_PROG(test_cpumask_null, struct task_struct *task, u64 clone_flags)
112{
113  /* NULL passed to KF_TRUSTED_ARGS kfunc. */
114	bpf_cpumask_empty(NULL);
115
116	return 0;
117}
118
119SEC("tp_btf/task_newtask")
120__failure __msg("R2 must be a rcu pointer")
121int BPF_PROG(test_global_mask_out_of_rcu, struct task_struct *task, u64 clone_flags)
122{
123	struct bpf_cpumask *local, *prev;
124
125	local = create_cpumask();
126	if (!local)
127		return 0;
128
129	prev = bpf_kptr_xchg(&global_mask, local);
130	if (prev) {
131		bpf_cpumask_release(prev);
132		err = 3;
133		return 0;
134	}
135
136	bpf_rcu_read_lock();
137	local = global_mask;
138	if (!local) {
139		err = 4;
140		bpf_rcu_read_unlock();
141		return 0;
142	}
143
144	bpf_rcu_read_unlock();
145
146	/* RCU region is exited before calling KF_RCU kfunc. */
147
148	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
149
150	return 0;
151}
152
153SEC("tp_btf/task_newtask")
154__failure __msg("NULL pointer passed to trusted arg1")
155int BPF_PROG(test_global_mask_no_null_check, struct task_struct *task, u64 clone_flags)
156{
157	struct bpf_cpumask *local, *prev;
158
159	local = create_cpumask();
160	if (!local)
161		return 0;
162
163	prev = bpf_kptr_xchg(&global_mask, local);
164	if (prev) {
165		bpf_cpumask_release(prev);
166		err = 3;
167		return 0;
168	}
169
170	bpf_rcu_read_lock();
171	local = global_mask;
172
173	/* No NULL check is performed on global cpumask kptr. */
174	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
175
176	bpf_rcu_read_unlock();
177
178	return 0;
179}
180
181SEC("tp_btf/task_newtask")
182__failure __msg("Possibly NULL pointer passed to helper arg2")
183int BPF_PROG(test_global_mask_rcu_no_null_check, struct task_struct *task, u64 clone_flags)
184{
185	struct bpf_cpumask *prev, *curr;
186
187	curr = bpf_cpumask_create();
188	if (!curr)
189		return 0;
190
191	prev = bpf_kptr_xchg(&global_mask, curr);
192	if (prev)
193		bpf_cpumask_release(prev);
194
195	bpf_rcu_read_lock();
196	curr = global_mask;
197	/* PTR_TO_BTF_ID | PTR_MAYBE_NULL | MEM_RCU passed to bpf_kptr_xchg() */
198	prev = bpf_kptr_xchg(&global_mask, curr);
199	bpf_rcu_read_unlock();
200	if (prev)
201		bpf_cpumask_release(prev);
202
203	return 0;
204}
205
206SEC("tp_btf/task_newtask")
207__failure __msg("has no valid kptr")
208int BPF_PROG(test_invalid_nested_array, struct task_struct *task, u64 clone_flags)
209{
210	struct bpf_cpumask *local, *prev;
211
212	local = create_cpumask();
213	if (!local)
214		return 0;
215
216	prev = bpf_kptr_xchg(&global_mask_nested_arr.d_1.d_2[CPUMASK_KPTR_FIELDS_MAX].mask, local);
217	if (prev) {
218		bpf_cpumask_release(prev);
219		err = 3;
220		return 0;
221	}
222
223	return 0;
224}
v6.8
  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
 11char _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
 19SEC("tp_btf/task_newtask")
 20__failure __msg("Unreleased reference")
 21int 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	__sink(cpumask);
 27
 28	/* cpumask is never released. */
 29	return 0;
 30}
 31
 32SEC("tp_btf/task_newtask")
 33__failure __msg("NULL pointer passed to trusted arg0")
 34int BPF_PROG(test_alloc_double_release, struct task_struct *task, u64 clone_flags)
 35{
 36	struct bpf_cpumask *cpumask;
 37
 38	cpumask = create_cpumask();
 39
 40	/* cpumask is released twice. */
 41	bpf_cpumask_release(cpumask);
 42	bpf_cpumask_release(cpumask);
 43
 44	return 0;
 45}
 46
 47SEC("tp_btf/task_newtask")
 48__failure __msg("must be referenced")
 49int BPF_PROG(test_acquire_wrong_cpumask, struct task_struct *task, u64 clone_flags)
 50{
 51	struct bpf_cpumask *cpumask;
 52
 53	/* Can't acquire a non-struct bpf_cpumask. */
 54	cpumask = bpf_cpumask_acquire((struct bpf_cpumask *)task->cpus_ptr);
 55	__sink(cpumask);
 56
 57	return 0;
 58}
 59
 60SEC("tp_btf/task_newtask")
 61__failure __msg("bpf_cpumask_set_cpu args#1 expected pointer to STRUCT bpf_cpumask")
 62int BPF_PROG(test_mutate_cpumask, struct task_struct *task, u64 clone_flags)
 63{
 64	struct bpf_cpumask *cpumask;
 65
 66	/* Can't set the CPU of a non-struct bpf_cpumask. */
 67	bpf_cpumask_set_cpu(0, (struct bpf_cpumask *)task->cpus_ptr);
 68	__sink(cpumask);
 69
 70	return 0;
 71}
 72
 73SEC("tp_btf/task_newtask")
 74__failure __msg("Unreleased reference")
 75int BPF_PROG(test_insert_remove_no_release, struct task_struct *task, u64 clone_flags)
 76{
 77	struct bpf_cpumask *cpumask;
 78	struct __cpumask_map_value *v;
 79
 80	cpumask = create_cpumask();
 81	if (!cpumask)
 82		return 0;
 83
 84	if (cpumask_map_insert(cpumask))
 85		return 0;
 86
 87	v = cpumask_map_value_lookup();
 88	if (!v)
 89		return 0;
 90
 91	cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
 92
 93	/* cpumask is never released. */
 94	return 0;
 95}
 96
 97SEC("tp_btf/task_newtask")
 98__failure __msg("NULL pointer passed to trusted arg0")
 99int BPF_PROG(test_cpumask_null, struct task_struct *task, u64 clone_flags)
100{
101  /* NULL passed to KF_TRUSTED_ARGS kfunc. */
102	bpf_cpumask_empty(NULL);
103
104	return 0;
105}
106
107SEC("tp_btf/task_newtask")
108__failure __msg("R2 must be a rcu pointer")
109int BPF_PROG(test_global_mask_out_of_rcu, struct task_struct *task, u64 clone_flags)
110{
111	struct bpf_cpumask *local, *prev;
112
113	local = create_cpumask();
114	if (!local)
115		return 0;
116
117	prev = bpf_kptr_xchg(&global_mask, local);
118	if (prev) {
119		bpf_cpumask_release(prev);
120		err = 3;
121		return 0;
122	}
123
124	bpf_rcu_read_lock();
125	local = global_mask;
126	if (!local) {
127		err = 4;
128		bpf_rcu_read_unlock();
129		return 0;
130	}
131
132	bpf_rcu_read_unlock();
133
134	/* RCU region is exited before calling KF_RCU kfunc. */
135
136	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
137
138	return 0;
139}
140
141SEC("tp_btf/task_newtask")
142__failure __msg("NULL pointer passed to trusted arg1")
143int BPF_PROG(test_global_mask_no_null_check, struct task_struct *task, u64 clone_flags)
144{
145	struct bpf_cpumask *local, *prev;
146
147	local = create_cpumask();
148	if (!local)
149		return 0;
150
151	prev = bpf_kptr_xchg(&global_mask, local);
152	if (prev) {
153		bpf_cpumask_release(prev);
154		err = 3;
155		return 0;
156	}
157
158	bpf_rcu_read_lock();
159	local = global_mask;
160
161	/* No NULL check is performed on global cpumask kptr. */
162	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
163
164	bpf_rcu_read_unlock();
165
166	return 0;
167}
168
169SEC("tp_btf/task_newtask")
170__failure __msg("Possibly NULL pointer passed to helper arg2")
171int BPF_PROG(test_global_mask_rcu_no_null_check, struct task_struct *task, u64 clone_flags)
172{
173	struct bpf_cpumask *prev, *curr;
174
175	curr = bpf_cpumask_create();
176	if (!curr)
177		return 0;
178
179	prev = bpf_kptr_xchg(&global_mask, curr);
180	if (prev)
181		bpf_cpumask_release(prev);
182
183	bpf_rcu_read_lock();
184	curr = global_mask;
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();
188	if (prev)
189		bpf_cpumask_release(prev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
191	return 0;
192}