FILE
verifier_vfs_reject.c
File preview with syntax highlighting.
linux-6.19.14/tools/testing/selftests/bpf/progs/verifier_vfs_reject.c
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 13static char buf[PATH_MAX]; 14 15SEC("lsm.s/file_open") 16__failure __msg("Possibly NULL pointer passed to trusted arg0") 17int 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 30SEC("lsm.s/inode_getxattr") 31__failure __msg("arg#0 pointer type STRUCT task_struct must point to scalar, or struct with scalar") 32int 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 48SEC("lsm.s/file_open") 49__failure __msg("R1 must be referenced or trusted") 50int 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 68SEC("lsm.s/file_open") 69__failure __msg("Unreleased reference") 70int 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 82SEC("lsm.s/file_open") 83__failure __msg("release kernel function bpf_put_file expects") 84int 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 91SEC("lsm.s/file_open") 92__failure __msg("Possibly NULL pointer passed to trusted arg0") 93int 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 100SEC("lsm.s/task_alloc") 101__failure __msg("R1 must be referenced or trusted") 102int 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 114SEC("lsm.s/file_open") 115__failure __msg("R1 must be referenced or trusted") 116int 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 130SEC("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") 132int 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 138SEC("lsm.s/file_open") 139__failure __msg("invalid access to map value, value_size=4096 off=0 size=8192") 140int 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 152SEC("fentry/vfs_open") 153__failure __msg("calling kernel function bpf_path_d_path is not allowed") 154int 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 162SEC("lsm.s/inode_rename") 163__failure __msg("invalid mem access 'trusted_ptr_or_null_'") 164int 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} 176char _license[] SEC("license") = "GPL";
~/
Read-only file preview.