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")
BPF_PROG(get_task_exe_file_kfunc_null)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")
BPF_PROG(get_task_exe_file_kfunc_fp)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")
BPF_PROG(get_task_exe_file_kfunc_untrusted)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")
BPF_PROG(get_task_exe_file_kfunc_unreleased)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")
BPF_PROG(put_file_kfunc_unacquired,struct file * file)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")
BPF_PROG(path_d_path_kfunc_null)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")
BPF_PROG(path_d_path_kfunc_untrusted_from_argument,struct task_struct * task)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")
BPF_PROG(path_d_path_kfunc_untrusted_from_current)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")
BPF_PROG(path_d_path_kfunc_type_mismatch,struct file * 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")
BPF_PROG(path_d_path_kfunc_invalid_buf_sz,struct file * file)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")
BPF_PROG(path_d_path_kfunc_non_lsm,struct path * path,struct file * f)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_'")
BPF_PROG(inode_rename,struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)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