1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024 Google LLC. */ 3 4 #include <vmlinux.h> 5 #include <errno.h> 6 #include <bpf/bpf_helpers.h> 7 #include <bpf/bpf_tracing.h> 8 #include <linux/limits.h> 9 10 #include "bpf_misc.h" 11 #include "bpf_experimental.h" 12 13 static char buf[PATH_MAX]; 14 15 SEC("lsm.s/file_open") 16 __failure __msg("Possibly NULL pointer passed to trusted arg0") 17 int BPF_PROG(get_task_exe_file_kfunc_null) 18 { 19 struct file *acquired; 20 21 /* Can't pass a NULL pointer to bpf_get_task_exe_file(). */ 22 acquired = bpf_get_task_exe_file(NULL); 23 if (!acquired) 24 return 0; 25 26 bpf_put_file(acquired); 27 return 0; 28 } 29 30 SEC("lsm.s/inode_getxattr") 31 __failure __msg("arg#0 pointer type STRUCT task_struct must point to scalar, or struct with scalar") 32 int BPF_PROG(get_task_exe_file_kfunc_fp) 33 { 34 u64 x; 35 struct file *acquired; 36 struct task_struct *task; 37 38 task = (struct task_struct *)&x; 39 /* Can't pass random frame pointer to bpf_get_task_exe_file(). */ 40 acquired = bpf_get_task_exe_file(task); 41 if (!acquired) 42 return 0; 43 44 bpf_put_file(acquired); 45 return 0; 46 } 47 48 SEC("lsm.s/file_open") 49 __failure __msg("R1 must be referenced or trusted") 50 int BPF_PROG(get_task_exe_file_kfunc_untrusted) 51 { 52 struct file *acquired; 53 struct task_struct *parent; 54 55 /* Walking a trusted struct task_struct returned from 56 * bpf_get_current_task_btf() yields an untrusted pointer. 57 */ 58 parent = bpf_get_current_task_btf()->parent; 59 /* Can't pass untrusted pointer to bpf_get_task_exe_file(). */ 60 acquired = bpf_get_task_exe_file(parent); 61 if (!acquired) 62 return 0; 63 64 bpf_put_file(acquired); 65 return 0; 66 } 67 68 SEC("lsm.s/file_open") 69 __failure __msg("Unreleased reference") 70 int BPF_PROG(get_task_exe_file_kfunc_unreleased) 71 { 72 struct file *acquired; 73 74 acquired = bpf_get_task_exe_file(bpf_get_current_task_btf()); 75 if (!acquired) 76 return 0; 77 78 /* Acquired but never released. */ 79 return 0; 80 } 81 82 SEC("lsm.s/file_open") 83 __failure __msg("release kernel function bpf_put_file expects") 84 int BPF_PROG(put_file_kfunc_unacquired, struct file *file) 85 { 86 /* Can't release an unacquired pointer. */ 87 bpf_put_file(file); 88 return 0; 89 } 90 91 SEC("lsm.s/file_open") 92 __failure __msg("Possibly NULL pointer passed to trusted arg0") 93 int BPF_PROG(path_d_path_kfunc_null) 94 { 95 /* Can't pass NULL value to bpf_path_d_path() kfunc. */ 96 bpf_path_d_path(NULL, buf, sizeof(buf)); 97 return 0; 98 } 99 100 SEC("lsm.s/task_alloc") 101 __failure __msg("R1 must be referenced or trusted") 102 int BPF_PROG(path_d_path_kfunc_untrusted_from_argument, struct task_struct *task) 103 { 104 struct path *root; 105 106 /* Walking a trusted argument typically yields an untrusted 107 * pointer. This is one example of that. 108 */ 109 root = &task->fs->root; 110 bpf_path_d_path(root, buf, sizeof(buf)); 111 return 0; 112 } 113 114 SEC("lsm.s/file_open") 115 __failure __msg("R1 must be referenced or trusted") 116 int BPF_PROG(path_d_path_kfunc_untrusted_from_current) 117 { 118 struct path *pwd; 119 struct task_struct *current; 120 121 current = bpf_get_current_task_btf(); 122 /* Walking a trusted pointer returned from bpf_get_current_task_btf() 123 * yields an untrusted pointer. 124 */ 125 pwd = ¤t->fs->pwd; 126 bpf_path_d_path(pwd, buf, sizeof(buf)); 127 return 0; 128 } 129 130 SEC("lsm.s/file_open") 131 __failure __msg("kernel function bpf_path_d_path args#0 expected pointer to STRUCT path but R1 has a pointer to STRUCT file") 132 int BPF_PROG(path_d_path_kfunc_type_mismatch, struct file *file) 133 { 134 bpf_path_d_path((struct path *)&file->f_task_work, buf, sizeof(buf)); 135 return 0; 136 } 137 138 SEC("lsm.s/file_open") 139 __failure __msg("invalid access to map value, value_size=4096 off=0 size=8192") 140 int BPF_PROG(path_d_path_kfunc_invalid_buf_sz, struct file *file) 141 { 142 /* bpf_path_d_path() enforces a constraint on the buffer size supplied 143 * by the BPF LSM program via the __sz annotation. buf here is set to 144 * PATH_MAX, so let's ensure that the BPF verifier rejects BPF_PROG_LOAD 145 * attempts if the supplied size and the actual size of the buffer 146 * mismatches. 147 */ 148 bpf_path_d_path(&file->f_path, buf, PATH_MAX * 2); 149 return 0; 150 } 151 152 SEC("fentry/vfs_open") 153 __failure __msg("calling kernel function bpf_path_d_path is not allowed") 154 int BPF_PROG(path_d_path_kfunc_non_lsm, struct path *path, struct file *f) 155 { 156 /* Calling bpf_path_d_path() from a non-LSM BPF program isn't permitted. 157 */ 158 bpf_path_d_path(path, buf, sizeof(buf)); 159 return 0; 160 } 161 162 SEC("lsm.s/inode_rename") 163 __failure __msg("invalid mem access 'trusted_ptr_or_null_'") 164 int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, 165 struct inode *new_dir, struct dentry *new_dentry, 166 unsigned int flags) 167 { 168 struct inode *inode = new_dentry->d_inode; 169 ino_t ino; 170 171 ino = inode->i_ino; 172 if (ino == 0) 173 return -EACCES; 174 return 0; 175 } 176 char _license[] SEC("license") = "GPL"; 177