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