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

Configure Feed

Select the types of activity you want to include in your feed.

at master 262 lines 5.8 kB view raw
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 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} 225 226SEC("tp_btf/task_newtask") 227__failure __msg("type=scalar expected=fp") 228int BPF_PROG(test_populate_invalid_destination, struct task_struct *task, u64 clone_flags) 229{ 230 struct bpf_cpumask *invalid = (struct bpf_cpumask *)0x123456; 231 u64 bits; 232 int ret; 233 234 ret = bpf_cpumask_populate((struct cpumask *)invalid, &bits, sizeof(bits)); 235 if (!ret) 236 err = 2; 237 238 return 0; 239} 240 241SEC("tp_btf/task_newtask") 242__failure __msg("leads to invalid memory access") 243int BPF_PROG(test_populate_invalid_source, struct task_struct *task, u64 clone_flags) 244{ 245 void *garbage = (void *)0x123456; 246 struct bpf_cpumask *local; 247 int ret; 248 249 local = create_cpumask(); 250 if (!local) { 251 err = 1; 252 return 0; 253 } 254 255 ret = bpf_cpumask_populate((struct cpumask *)local, garbage, 8); 256 if (!ret) 257 err = 2; 258 259 bpf_cpumask_release(local); 260 261 return 0; 262}