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 310 lines 8.2 kB view raw
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_helpers.h> 6#include <bpf/bpf_tracing.h> 7#include <bpf/bpf_core_read.h> 8#include "bpf_misc.h" 9#include "xdp_metadata.h" 10#include "bpf_kfuncs.h" 11 12extern struct task_struct *bpf_task_acquire(struct task_struct *p) __ksym __weak; 13extern void bpf_task_release(struct task_struct *p) __ksym __weak; 14 15__weak int subprog_trusted_task_nullable(struct task_struct *task __arg_trusted __arg_nullable) 16{ 17 if (!task) 18 return 0; 19 return task->pid + task->tgid; 20} 21 22__weak int subprog_trusted_task_nullable_extra_layer(struct task_struct *task __arg_trusted __arg_nullable) 23{ 24 return subprog_trusted_task_nullable(task) + subprog_trusted_task_nullable(NULL); 25} 26 27SEC("?tp_btf/task_newtask") 28__success __log_level(2) 29__msg("Validating subprog_trusted_task_nullable() func#1...") 30__msg(": R1=trusted_ptr_or_null_task_struct(") 31int trusted_task_arg_nullable(void *ctx) 32{ 33 struct task_struct *t1 = bpf_get_current_task_btf(); 34 struct task_struct *t2 = bpf_task_acquire(t1); 35 int res = 0; 36 37 /* known NULL */ 38 res += subprog_trusted_task_nullable(NULL); 39 40 /* known non-NULL */ 41 res += subprog_trusted_task_nullable(t1); 42 res += subprog_trusted_task_nullable_extra_layer(t1); 43 44 /* unknown if NULL or not */ 45 res += subprog_trusted_task_nullable(t2); 46 res += subprog_trusted_task_nullable_extra_layer(t2); 47 48 if (t2) { 49 /* known non-NULL after explicit NULL check, just in case */ 50 res += subprog_trusted_task_nullable(t2); 51 res += subprog_trusted_task_nullable_extra_layer(t2); 52 53 bpf_task_release(t2); 54 } 55 56 return res; 57} 58 59__weak int subprog_trusted_task_nonnull(struct task_struct *task __arg_trusted) 60{ 61 return task->pid + task->tgid; 62} 63 64SEC("?kprobe") 65__failure __log_level(2) 66__msg("R1 type=scalar expected=ptr_, trusted_ptr_, rcu_ptr_") 67__msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')") 68int trusted_task_arg_nonnull_fail1(void *ctx) 69{ 70 return subprog_trusted_task_nonnull(NULL); 71} 72 73SEC("?tp_btf/task_newtask") 74__failure __log_level(2) 75__msg("R1 type=trusted_ptr_or_null_ expected=ptr_, trusted_ptr_, rcu_ptr_") 76__msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')") 77int trusted_task_arg_nonnull_fail2(void *ctx) 78{ 79 struct task_struct *t = bpf_get_current_task_btf(); 80 struct task_struct *nullable; 81 int res; 82 83 nullable = bpf_task_acquire(t); 84 85 /* should fail, PTR_TO_BTF_ID_OR_NULL */ 86 res = subprog_trusted_task_nonnull(nullable); 87 88 if (nullable) 89 bpf_task_release(nullable); 90 91 return res; 92} 93 94SEC("?kprobe") 95__success __log_level(2) 96__msg("Validating subprog_trusted_task_nonnull() func#1...") 97__msg(": R1=trusted_ptr_task_struct(") 98int trusted_task_arg_nonnull(void *ctx) 99{ 100 struct task_struct *t = bpf_get_current_task_btf(); 101 102 return subprog_trusted_task_nonnull(t); 103} 104 105struct task_struct___local {} __attribute__((preserve_access_index)); 106 107__weak int subprog_nullable_task_flavor( 108 struct task_struct___local *task __arg_trusted __arg_nullable) 109{ 110 char buf[16]; 111 112 if (!task) 113 return 0; 114 115 return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0); 116} 117 118SEC("?uprobe.s") 119__success __log_level(2) 120__msg("Validating subprog_nullable_task_flavor() func#1...") 121__msg(": R1=trusted_ptr_or_null_task_struct(") 122int flavor_ptr_nullable(void *ctx) 123{ 124 struct task_struct___local *t = (void *)bpf_get_current_task_btf(); 125 126 return subprog_nullable_task_flavor(t); 127} 128 129__weak int subprog_nonnull_task_flavor(struct task_struct___local *task __arg_trusted) 130{ 131 char buf[16]; 132 133 return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0); 134} 135 136SEC("?uprobe.s") 137__success __log_level(2) 138__msg("Validating subprog_nonnull_task_flavor() func#1...") 139__msg(": R1=trusted_ptr_task_struct(") 140int flavor_ptr_nonnull(void *ctx) 141{ 142 struct task_struct *t = bpf_get_current_task_btf(); 143 144 return subprog_nonnull_task_flavor((void *)t); 145} 146 147__weak int subprog_trusted_destroy(struct task_struct *task __arg_trusted) 148{ 149 bpf_task_release(task); /* should be rejected */ 150 151 return 0; 152} 153 154SEC("?tp_btf/task_newtask") 155__failure __log_level(2) 156__msg("release kernel function bpf_task_release expects refcounted PTR_TO_BTF_ID") 157int BPF_PROG(trusted_destroy_fail, struct task_struct *task, u64 clone_flags) 158{ 159 return subprog_trusted_destroy(task); 160} 161 162__weak int subprog_trusted_acq_rel(struct task_struct *task __arg_trusted) 163{ 164 struct task_struct *owned; 165 166 owned = bpf_task_acquire(task); 167 if (!owned) 168 return 0; 169 170 bpf_task_release(owned); /* this one is OK, we acquired it locally */ 171 172 return 0; 173} 174 175SEC("?tp_btf/task_newtask") 176__success __log_level(2) 177int BPF_PROG(trusted_acq_rel, struct task_struct *task, u64 clone_flags) 178{ 179 return subprog_trusted_acq_rel(task); 180} 181 182__weak int subprog_untrusted_bad_tags(struct task_struct *task __arg_untrusted __arg_nullable) 183{ 184 return task->pid; 185} 186 187SEC("tp_btf/sys_enter") 188__failure 189__msg("arg#0 untrusted cannot be combined with any other tags") 190int untrusted_bad_tags(void *ctx) 191{ 192 return subprog_untrusted_bad_tags(0); 193} 194 195struct local_type_wont_be_accepted {}; 196 197__weak int subprog_untrusted_bad_type(struct local_type_wont_be_accepted *p __arg_untrusted) 198{ 199 return 0; 200} 201 202SEC("tp_btf/sys_enter") 203__failure 204__msg("arg#0 reference type('STRUCT local_type_wont_be_accepted') has no matches") 205int untrusted_bad_type(void *ctx) 206{ 207 return subprog_untrusted_bad_type(bpf_rdonly_cast(0, 0)); 208} 209 210__weak int subprog_untrusted(const volatile struct task_struct *restrict task __arg_untrusted) 211{ 212 return task->pid; 213} 214 215SEC("tp_btf/sys_enter") 216__success 217__log_level(2) 218__msg("r1 = {{.*}}; {{.*}}R1=trusted_ptr_task_struct()") 219__msg("Func#1 ('subprog_untrusted') is global and assumed valid.") 220__msg("Validating subprog_untrusted() func#1...") 221__msg(": R1=untrusted_ptr_task_struct") 222int trusted_to_untrusted(void *ctx) 223{ 224 return subprog_untrusted(bpf_get_current_task_btf()); 225} 226 227char mem[16]; 228u32 offset; 229 230SEC("tp_btf/sys_enter") 231__success 232int anything_to_untrusted(void *ctx) 233{ 234 /* untrusted to untrusted */ 235 subprog_untrusted(bpf_core_cast(0, struct task_struct)); 236 /* wrong type to untrusted */ 237 subprog_untrusted((void *)bpf_core_cast(0, struct bpf_verifier_env)); 238 /* map value to untrusted */ 239 subprog_untrusted((void *)mem); 240 /* scalar to untrusted */ 241 subprog_untrusted(0); 242 /* variable offset to untrusted (map) */ 243 subprog_untrusted((void *)mem + offset); 244 /* variable offset to untrusted (trusted) */ 245 subprog_untrusted((void *)bpf_get_current_task_btf() + offset); 246 return 0; 247} 248 249__weak int subprog_untrusted2(struct task_struct *task __arg_untrusted) 250{ 251 return subprog_trusted_task_nullable(task); 252} 253 254SEC("tp_btf/sys_enter") 255__failure 256__msg("R1 type=untrusted_ptr_ expected=ptr_, trusted_ptr_, rcu_ptr_") 257__msg("Caller passes invalid args into func#{{.*}} ('subprog_trusted_task_nullable')") 258int untrusted_to_trusted(void *ctx) 259{ 260 return subprog_untrusted2(bpf_get_current_task_btf()); 261} 262 263__weak int subprog_void_untrusted(void *p __arg_untrusted) 264{ 265 return *(int *)p; 266} 267 268__weak int subprog_char_untrusted(char *p __arg_untrusted) 269{ 270 return *(int *)p; 271} 272 273__weak int subprog_enum_untrusted(enum bpf_attach_type *p __arg_untrusted) 274{ 275 return *(int *)p; 276} 277 278SEC("tp_btf/sys_enter") 279__success 280__log_level(2) 281__msg("r1 = {{.*}}; {{.*}}R1=trusted_ptr_task_struct()") 282__msg("Func#1 ('subprog_void_untrusted') is global and assumed valid.") 283__msg("Validating subprog_void_untrusted() func#1...") 284__msg(": R1=rdonly_untrusted_mem(sz=0)") 285int trusted_to_untrusted_mem(void *ctx) 286{ 287 return subprog_void_untrusted(bpf_get_current_task_btf()); 288} 289 290SEC("tp_btf/sys_enter") 291__success 292int anything_to_untrusted_mem(void *ctx) 293{ 294 /* untrusted to untrusted mem */ 295 subprog_void_untrusted(bpf_core_cast(0, struct task_struct)); 296 /* map value to untrusted mem */ 297 subprog_void_untrusted(mem); 298 /* scalar to untrusted mem */ 299 subprog_void_untrusted(0); 300 /* variable offset to untrusted mem (map) */ 301 subprog_void_untrusted((void *)mem + offset); 302 /* variable offset to untrusted mem (trusted) */ 303 subprog_void_untrusted(bpf_get_current_task_btf() + offset); 304 /* variable offset to untrusted char/enum (map) */ 305 subprog_char_untrusted(mem + offset); 306 subprog_enum_untrusted((void *)mem + offset); 307 return 0; 308} 309 310char _license[] SEC("license") = "GPL";