xref: /linux/fs/bpf_fs_kfuncs.c (revision 56467292794b800164df20c076c409ac548e56ec)
1d08e2045SMatt Bobrowski // SPDX-License-Identifier: GPL-2.0
2d08e2045SMatt Bobrowski /* Copyright (c) 2024 Google LLC. */
3d08e2045SMatt Bobrowski 
4d08e2045SMatt Bobrowski #include <linux/bpf.h>
5*56467292SSong Liu #include <linux/bpf_lsm.h>
6d08e2045SMatt Bobrowski #include <linux/btf.h>
7d08e2045SMatt Bobrowski #include <linux/btf_ids.h>
8d08e2045SMatt Bobrowski #include <linux/dcache.h>
9d08e2045SMatt Bobrowski #include <linux/fs.h>
10*56467292SSong Liu #include <linux/fsnotify.h>
11d08e2045SMatt Bobrowski #include <linux/file.h>
12d08e2045SMatt Bobrowski #include <linux/mm.h>
13fa4e5afaSSong Liu #include <linux/xattr.h>
14d08e2045SMatt Bobrowski 
15d08e2045SMatt Bobrowski __bpf_kfunc_start_defs();
16d08e2045SMatt Bobrowski 
17d08e2045SMatt Bobrowski /**
18d08e2045SMatt Bobrowski  * bpf_get_task_exe_file - get a reference on the exe_file struct file member of
19d08e2045SMatt Bobrowski  *                         the mm_struct that is nested within the supplied
20d08e2045SMatt Bobrowski  *                         task_struct
21d08e2045SMatt Bobrowski  * @task: task_struct of which the nested mm_struct exe_file member to get a
22d08e2045SMatt Bobrowski  * reference on
23d08e2045SMatt Bobrowski  *
24d08e2045SMatt Bobrowski  * Get a reference on the exe_file struct file member field of the mm_struct
25d08e2045SMatt Bobrowski  * nested within the supplied *task*. The referenced file pointer acquired by
26d08e2045SMatt Bobrowski  * this BPF kfunc must be released using bpf_put_file(). Failing to call
27d08e2045SMatt Bobrowski  * bpf_put_file() on the returned referenced struct file pointer that has been
28d08e2045SMatt Bobrowski  * acquired by this BPF kfunc will result in the BPF program being rejected by
29d08e2045SMatt Bobrowski  * the BPF verifier.
30d08e2045SMatt Bobrowski  *
31d08e2045SMatt Bobrowski  * This BPF kfunc may only be called from BPF LSM programs.
32d08e2045SMatt Bobrowski  *
33d08e2045SMatt Bobrowski  * Internally, this BPF kfunc leans on get_task_exe_file(), such that calling
34d08e2045SMatt Bobrowski  * bpf_get_task_exe_file() would be analogous to calling get_task_exe_file()
35d08e2045SMatt Bobrowski  * directly in kernel context.
36d08e2045SMatt Bobrowski  *
37d08e2045SMatt Bobrowski  * Return: A referenced struct file pointer to the exe_file member of the
38d08e2045SMatt Bobrowski  * mm_struct that is nested within the supplied *task*. On error, NULL is
39d08e2045SMatt Bobrowski  * returned.
40d08e2045SMatt Bobrowski  */
41d08e2045SMatt Bobrowski __bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task)
42d08e2045SMatt Bobrowski {
43d08e2045SMatt Bobrowski 	return get_task_exe_file(task);
44d08e2045SMatt Bobrowski }
45d08e2045SMatt Bobrowski 
46d08e2045SMatt Bobrowski /**
47d08e2045SMatt Bobrowski  * bpf_put_file - put a reference on the supplied file
48d08e2045SMatt Bobrowski  * @file: file to put a reference on
49d08e2045SMatt Bobrowski  *
50d08e2045SMatt Bobrowski  * Put a reference on the supplied *file*. Only referenced file pointers may be
51d08e2045SMatt Bobrowski  * passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or
52d08e2045SMatt Bobrowski  * any other arbitrary pointer for that matter, will result in the BPF program
53d08e2045SMatt Bobrowski  * being rejected by the BPF verifier.
54d08e2045SMatt Bobrowski  *
55d08e2045SMatt Bobrowski  * This BPF kfunc may only be called from BPF LSM programs.
56d08e2045SMatt Bobrowski  */
57d08e2045SMatt Bobrowski __bpf_kfunc void bpf_put_file(struct file *file)
58d08e2045SMatt Bobrowski {
59d08e2045SMatt Bobrowski 	fput(file);
60d08e2045SMatt Bobrowski }
61d08e2045SMatt Bobrowski 
62d08e2045SMatt Bobrowski /**
63d08e2045SMatt Bobrowski  * bpf_path_d_path - resolve the pathname for the supplied path
64d08e2045SMatt Bobrowski  * @path: path to resolve the pathname for
65d08e2045SMatt Bobrowski  * @buf: buffer to return the resolved pathname in
66d08e2045SMatt Bobrowski  * @buf__sz: length of the supplied buffer
67d08e2045SMatt Bobrowski  *
68d08e2045SMatt Bobrowski  * Resolve the pathname for the supplied *path* and store it in *buf*. This BPF
69d08e2045SMatt Bobrowski  * kfunc is the safer variant of the legacy bpf_d_path() helper and should be
70d08e2045SMatt Bobrowski  * used in place of bpf_d_path() whenever possible. It enforces KF_TRUSTED_ARGS
71d08e2045SMatt Bobrowski  * semantics, meaning that the supplied *path* must itself hold a valid
72d08e2045SMatt Bobrowski  * reference, or else the BPF program will be outright rejected by the BPF
73d08e2045SMatt Bobrowski  * verifier.
74d08e2045SMatt Bobrowski  *
75d08e2045SMatt Bobrowski  * This BPF kfunc may only be called from BPF LSM programs.
76d08e2045SMatt Bobrowski  *
77d08e2045SMatt Bobrowski  * Return: A positive integer corresponding to the length of the resolved
78d08e2045SMatt Bobrowski  * pathname in *buf*, including the NUL termination character. On error, a
79d08e2045SMatt Bobrowski  * negative integer is returned.
80d08e2045SMatt Bobrowski  */
81d08e2045SMatt Bobrowski __bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)
82d08e2045SMatt Bobrowski {
83d08e2045SMatt Bobrowski 	int len;
84d08e2045SMatt Bobrowski 	char *ret;
85d08e2045SMatt Bobrowski 
86d08e2045SMatt Bobrowski 	if (!buf__sz)
87d08e2045SMatt Bobrowski 		return -EINVAL;
88d08e2045SMatt Bobrowski 
89d08e2045SMatt Bobrowski 	ret = d_path(path, buf, buf__sz);
90d08e2045SMatt Bobrowski 	if (IS_ERR(ret))
91d08e2045SMatt Bobrowski 		return PTR_ERR(ret);
92d08e2045SMatt Bobrowski 
93d08e2045SMatt Bobrowski 	len = buf + buf__sz - ret;
94d08e2045SMatt Bobrowski 	memmove(buf, ret, len);
95d08e2045SMatt Bobrowski 	return len;
96d08e2045SMatt Bobrowski }
97d08e2045SMatt Bobrowski 
98531118f1SSong Liu static bool match_security_bpf_prefix(const char *name__str)
99531118f1SSong Liu {
100531118f1SSong Liu 	return !strncmp(name__str, XATTR_NAME_BPF_LSM, XATTR_NAME_BPF_LSM_LEN);
101531118f1SSong Liu }
102531118f1SSong Liu 
103531118f1SSong Liu static int bpf_xattr_read_permission(const char *name, struct inode *inode)
104531118f1SSong Liu {
105531118f1SSong Liu 	if (WARN_ON(!inode))
106531118f1SSong Liu 		return -EINVAL;
107531118f1SSong Liu 
108531118f1SSong Liu 	/* Allow reading xattr with user. and security.bpf. prefix */
109531118f1SSong Liu 	if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
110531118f1SSong Liu 	    !match_security_bpf_prefix(name))
111531118f1SSong Liu 		return -EPERM;
112531118f1SSong Liu 
113531118f1SSong Liu 	return inode_permission(&nop_mnt_idmap, inode, MAY_READ);
114531118f1SSong Liu }
115531118f1SSong Liu 
116fa4e5afaSSong Liu /**
117ac13a426SSong Liu  * bpf_get_dentry_xattr - get xattr of a dentry
118ac13a426SSong Liu  * @dentry: dentry to get xattr from
119ac13a426SSong Liu  * @name__str: name of the xattr
120ac13a426SSong Liu  * @value_p: output buffer of the xattr value
121ac13a426SSong Liu  *
122ac13a426SSong Liu  * Get xattr *name__str* of *dentry* and store the output in *value_ptr*.
123ac13a426SSong Liu  *
124531118f1SSong Liu  * For security reasons, only *name__str* with prefixes "user." or
125531118f1SSong Liu  * "security.bpf." are allowed.
126ac13a426SSong Liu  *
127531118f1SSong Liu  * Return: length of the xattr value on success, a negative value on error.
128ac13a426SSong Liu  */
129ac13a426SSong Liu __bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str,
130ac13a426SSong Liu 				     struct bpf_dynptr *value_p)
131ac13a426SSong Liu {
132ac13a426SSong Liu 	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
133ac13a426SSong Liu 	struct inode *inode = d_inode(dentry);
134ac13a426SSong Liu 	u32 value_len;
135ac13a426SSong Liu 	void *value;
136ac13a426SSong Liu 	int ret;
137ac13a426SSong Liu 
138ac13a426SSong Liu 	value_len = __bpf_dynptr_size(value_ptr);
139ac13a426SSong Liu 	value = __bpf_dynptr_data_rw(value_ptr, value_len);
140ac13a426SSong Liu 	if (!value)
141ac13a426SSong Liu 		return -EINVAL;
142ac13a426SSong Liu 
143531118f1SSong Liu 	ret = bpf_xattr_read_permission(name__str, inode);
144ac13a426SSong Liu 	if (ret)
145ac13a426SSong Liu 		return ret;
146ac13a426SSong Liu 	return __vfs_getxattr(dentry, inode, name__str, value, value_len);
147ac13a426SSong Liu }
148ac13a426SSong Liu 
149ac13a426SSong Liu /**
150fa4e5afaSSong Liu  * bpf_get_file_xattr - get xattr of a file
151fa4e5afaSSong Liu  * @file: file to get xattr from
152fa4e5afaSSong Liu  * @name__str: name of the xattr
153fa4e5afaSSong Liu  * @value_p: output buffer of the xattr value
154fa4e5afaSSong Liu  *
155fa4e5afaSSong Liu  * Get xattr *name__str* of *file* and store the output in *value_ptr*.
156fa4e5afaSSong Liu  *
157531118f1SSong Liu  * For security reasons, only *name__str* with prefixes "user." or
158531118f1SSong Liu  * "security.bpf." are allowed.
159fa4e5afaSSong Liu  *
160531118f1SSong Liu  * Return: length of the xattr value on success, a negative value on error.
161fa4e5afaSSong Liu  */
162fa4e5afaSSong Liu __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
163fa4e5afaSSong Liu 				   struct bpf_dynptr *value_p)
164fa4e5afaSSong Liu {
165fa4e5afaSSong Liu 	struct dentry *dentry;
166fa4e5afaSSong Liu 
167fa4e5afaSSong Liu 	dentry = file_dentry(file);
168ac13a426SSong Liu 	return bpf_get_dentry_xattr(dentry, name__str, value_p);
169fa4e5afaSSong Liu }
170fa4e5afaSSong Liu 
171d08e2045SMatt Bobrowski __bpf_kfunc_end_defs();
172d08e2045SMatt Bobrowski 
173*56467292SSong Liu static int bpf_xattr_write_permission(const char *name, struct inode *inode)
174*56467292SSong Liu {
175*56467292SSong Liu 	if (WARN_ON(!inode))
176*56467292SSong Liu 		return -EINVAL;
177*56467292SSong Liu 
178*56467292SSong Liu 	/* Only allow setting and removing security.bpf. xattrs */
179*56467292SSong Liu 	if (!match_security_bpf_prefix(name))
180*56467292SSong Liu 		return -EPERM;
181*56467292SSong Liu 
182*56467292SSong Liu 	return inode_permission(&nop_mnt_idmap, inode, MAY_WRITE);
183*56467292SSong Liu }
184*56467292SSong Liu 
185*56467292SSong Liu /**
186*56467292SSong Liu  * bpf_set_dentry_xattr_locked - set a xattr of a dentry
187*56467292SSong Liu  * @dentry: dentry to get xattr from
188*56467292SSong Liu  * @name__str: name of the xattr
189*56467292SSong Liu  * @value_p: xattr value
190*56467292SSong Liu  * @flags: flags to pass into filesystem operations
191*56467292SSong Liu  *
192*56467292SSong Liu  * Set xattr *name__str* of *dentry* to the value in *value_ptr*.
193*56467292SSong Liu  *
194*56467292SSong Liu  * For security reasons, only *name__str* with prefix "security.bpf."
195*56467292SSong Liu  * is allowed.
196*56467292SSong Liu  *
197*56467292SSong Liu  * The caller already locked dentry->d_inode.
198*56467292SSong Liu  *
199*56467292SSong Liu  * Return: 0 on success, a negative value on error.
200*56467292SSong Liu  */
201*56467292SSong Liu int bpf_set_dentry_xattr_locked(struct dentry *dentry, const char *name__str,
202*56467292SSong Liu 				const struct bpf_dynptr *value_p, int flags)
203*56467292SSong Liu {
204*56467292SSong Liu 
205*56467292SSong Liu 	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
206*56467292SSong Liu 	struct inode *inode = d_inode(dentry);
207*56467292SSong Liu 	const void *value;
208*56467292SSong Liu 	u32 value_len;
209*56467292SSong Liu 	int ret;
210*56467292SSong Liu 
211*56467292SSong Liu 	value_len = __bpf_dynptr_size(value_ptr);
212*56467292SSong Liu 	value = __bpf_dynptr_data(value_ptr, value_len);
213*56467292SSong Liu 	if (!value)
214*56467292SSong Liu 		return -EINVAL;
215*56467292SSong Liu 
216*56467292SSong Liu 	ret = bpf_xattr_write_permission(name__str, inode);
217*56467292SSong Liu 	if (ret)
218*56467292SSong Liu 		return ret;
219*56467292SSong Liu 
220*56467292SSong Liu 	ret = __vfs_setxattr(&nop_mnt_idmap, dentry, inode, name__str,
221*56467292SSong Liu 			     value, value_len, flags);
222*56467292SSong Liu 	if (!ret) {
223*56467292SSong Liu 		fsnotify_xattr(dentry);
224*56467292SSong Liu 
225*56467292SSong Liu 		/* This xattr is set by BPF LSM, so we do not call
226*56467292SSong Liu 		 * security_inode_post_setxattr. Otherwise, we would
227*56467292SSong Liu 		 * risk deadlocks by calling back to the same kfunc.
228*56467292SSong Liu 		 *
229*56467292SSong Liu 		 * This is the same as security_inode_setsecurity().
230*56467292SSong Liu 		 */
231*56467292SSong Liu 	}
232*56467292SSong Liu 	return ret;
233*56467292SSong Liu }
234*56467292SSong Liu 
235*56467292SSong Liu /**
236*56467292SSong Liu  * bpf_remove_dentry_xattr_locked - remove a xattr of a dentry
237*56467292SSong Liu  * @dentry: dentry to get xattr from
238*56467292SSong Liu  * @name__str: name of the xattr
239*56467292SSong Liu  *
240*56467292SSong Liu  * Rmove xattr *name__str* of *dentry*.
241*56467292SSong Liu  *
242*56467292SSong Liu  * For security reasons, only *name__str* with prefix "security.bpf."
243*56467292SSong Liu  * is allowed.
244*56467292SSong Liu  *
245*56467292SSong Liu  * The caller already locked dentry->d_inode.
246*56467292SSong Liu  *
247*56467292SSong Liu  * Return: 0 on success, a negative value on error.
248*56467292SSong Liu  */
249*56467292SSong Liu int bpf_remove_dentry_xattr_locked(struct dentry *dentry, const char *name__str)
250*56467292SSong Liu {
251*56467292SSong Liu 	struct inode *inode = d_inode(dentry);
252*56467292SSong Liu 	int ret;
253*56467292SSong Liu 
254*56467292SSong Liu 	ret = bpf_xattr_write_permission(name__str, inode);
255*56467292SSong Liu 	if (ret)
256*56467292SSong Liu 		return ret;
257*56467292SSong Liu 
258*56467292SSong Liu 	ret = __vfs_removexattr(&nop_mnt_idmap, dentry, name__str);
259*56467292SSong Liu 	if (!ret) {
260*56467292SSong Liu 		fsnotify_xattr(dentry);
261*56467292SSong Liu 
262*56467292SSong Liu 		/* This xattr is removed by BPF LSM, so we do not call
263*56467292SSong Liu 		 * security_inode_post_removexattr. Otherwise, we would
264*56467292SSong Liu 		 * risk deadlocks by calling back to the same kfunc.
265*56467292SSong Liu 		 */
266*56467292SSong Liu 	}
267*56467292SSong Liu 	return ret;
268*56467292SSong Liu }
269*56467292SSong Liu 
270*56467292SSong Liu __bpf_kfunc_start_defs();
271*56467292SSong Liu 
272*56467292SSong Liu /**
273*56467292SSong Liu  * bpf_set_dentry_xattr - set a xattr of a dentry
274*56467292SSong Liu  * @dentry: dentry to get xattr from
275*56467292SSong Liu  * @name__str: name of the xattr
276*56467292SSong Liu  * @value_p: xattr value
277*56467292SSong Liu  * @flags: flags to pass into filesystem operations
278*56467292SSong Liu  *
279*56467292SSong Liu  * Set xattr *name__str* of *dentry* to the value in *value_ptr*.
280*56467292SSong Liu  *
281*56467292SSong Liu  * For security reasons, only *name__str* with prefix "security.bpf."
282*56467292SSong Liu  * is allowed.
283*56467292SSong Liu  *
284*56467292SSong Liu  * The caller has not locked dentry->d_inode.
285*56467292SSong Liu  *
286*56467292SSong Liu  * Return: 0 on success, a negative value on error.
287*56467292SSong Liu  */
288*56467292SSong Liu __bpf_kfunc int bpf_set_dentry_xattr(struct dentry *dentry, const char *name__str,
289*56467292SSong Liu 				     const struct bpf_dynptr *value_p, int flags)
290*56467292SSong Liu {
291*56467292SSong Liu 	struct inode *inode = d_inode(dentry);
292*56467292SSong Liu 	int ret;
293*56467292SSong Liu 
294*56467292SSong Liu 	inode_lock(inode);
295*56467292SSong Liu 	ret = bpf_set_dentry_xattr_locked(dentry, name__str, value_p, flags);
296*56467292SSong Liu 	inode_unlock(inode);
297*56467292SSong Liu 	return ret;
298*56467292SSong Liu }
299*56467292SSong Liu 
300*56467292SSong Liu /**
301*56467292SSong Liu  * bpf_remove_dentry_xattr - remove a xattr of a dentry
302*56467292SSong Liu  * @dentry: dentry to get xattr from
303*56467292SSong Liu  * @name__str: name of the xattr
304*56467292SSong Liu  *
305*56467292SSong Liu  * Rmove xattr *name__str* of *dentry*.
306*56467292SSong Liu  *
307*56467292SSong Liu  * For security reasons, only *name__str* with prefix "security.bpf."
308*56467292SSong Liu  * is allowed.
309*56467292SSong Liu  *
310*56467292SSong Liu  * The caller has not locked dentry->d_inode.
311*56467292SSong Liu  *
312*56467292SSong Liu  * Return: 0 on success, a negative value on error.
313*56467292SSong Liu  */
314*56467292SSong Liu __bpf_kfunc int bpf_remove_dentry_xattr(struct dentry *dentry, const char *name__str)
315*56467292SSong Liu {
316*56467292SSong Liu 	struct inode *inode = d_inode(dentry);
317*56467292SSong Liu 	int ret;
318*56467292SSong Liu 
319*56467292SSong Liu 	inode_lock(inode);
320*56467292SSong Liu 	ret = bpf_remove_dentry_xattr_locked(dentry, name__str);
321*56467292SSong Liu 	inode_unlock(inode);
322*56467292SSong Liu 	return ret;
323*56467292SSong Liu }
324*56467292SSong Liu 
325*56467292SSong Liu __bpf_kfunc_end_defs();
326*56467292SSong Liu 
327d08e2045SMatt Bobrowski BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)
328d08e2045SMatt Bobrowski BTF_ID_FLAGS(func, bpf_get_task_exe_file,
329d08e2045SMatt Bobrowski 	     KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL)
330d08e2045SMatt Bobrowski BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)
331d08e2045SMatt Bobrowski BTF_ID_FLAGS(func, bpf_path_d_path, KF_TRUSTED_ARGS)
332ac13a426SSong Liu BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
333fa4e5afaSSong Liu BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
334*56467292SSong Liu BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
335*56467292SSong Liu BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
336d08e2045SMatt Bobrowski BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)
337d08e2045SMatt Bobrowski 
338d08e2045SMatt Bobrowski static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
339d08e2045SMatt Bobrowski {
340d08e2045SMatt Bobrowski 	if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||
341d08e2045SMatt Bobrowski 	    prog->type == BPF_PROG_TYPE_LSM)
342d08e2045SMatt Bobrowski 		return 0;
343d08e2045SMatt Bobrowski 	return -EACCES;
344d08e2045SMatt Bobrowski }
345d08e2045SMatt Bobrowski 
346*56467292SSong Liu /* bpf_[set|remove]_dentry_xattr.* hooks have KF_TRUSTED_ARGS and
347*56467292SSong Liu  * KF_SLEEPABLE, so they are only available to sleepable hooks with
348*56467292SSong Liu  * dentry arguments.
349*56467292SSong Liu  *
350*56467292SSong Liu  * Setting and removing xattr requires exclusive lock on dentry->d_inode.
351*56467292SSong Liu  * Some hooks already locked d_inode, while some hooks have not locked
352*56467292SSong Liu  * d_inode. Therefore, we need different kfuncs for different hooks.
353*56467292SSong Liu  * Specifically, hooks in the following list (d_inode_locked_hooks)
354*56467292SSong Liu  * should call bpf_[set|remove]_dentry_xattr_locked; while other hooks
355*56467292SSong Liu  * should call bpf_[set|remove]_dentry_xattr.
356*56467292SSong Liu  */
357*56467292SSong Liu BTF_SET_START(d_inode_locked_hooks)
358*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_post_removexattr)
359*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_post_setattr)
360*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_post_setxattr)
361*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_removexattr)
362*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_rmdir)
363*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_setattr)
364*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_setxattr)
365*56467292SSong Liu BTF_ID(func, bpf_lsm_inode_unlink)
366*56467292SSong Liu #ifdef CONFIG_SECURITY_PATH
367*56467292SSong Liu BTF_ID(func, bpf_lsm_path_unlink)
368*56467292SSong Liu BTF_ID(func, bpf_lsm_path_rmdir)
369*56467292SSong Liu #endif /* CONFIG_SECURITY_PATH */
370*56467292SSong Liu BTF_SET_END(d_inode_locked_hooks)
371*56467292SSong Liu 
372*56467292SSong Liu bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog)
373*56467292SSong Liu {
374*56467292SSong Liu 	return btf_id_set_contains(&d_inode_locked_hooks, prog->aux->attach_btf_id);
375*56467292SSong Liu }
376*56467292SSong Liu 
377d08e2045SMatt Bobrowski static const struct btf_kfunc_id_set bpf_fs_kfunc_set = {
378d08e2045SMatt Bobrowski 	.owner = THIS_MODULE,
379d08e2045SMatt Bobrowski 	.set = &bpf_fs_kfunc_set_ids,
380d08e2045SMatt Bobrowski 	.filter = bpf_fs_kfuncs_filter,
381d08e2045SMatt Bobrowski };
382d08e2045SMatt Bobrowski 
383d08e2045SMatt Bobrowski static int __init bpf_fs_kfuncs_init(void)
384d08e2045SMatt Bobrowski {
385d08e2045SMatt Bobrowski 	return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set);
386d08e2045SMatt Bobrowski }
387d08e2045SMatt Bobrowski 
388d08e2045SMatt Bobrowski late_initcall(bpf_fs_kfuncs_init);
389