// SPDX-License-Identifier: GPL-2.01/* Copyright (c) 2024 Google LLC. */23#include <linux/bpf.h>4#include <linux/bpf_lsm.h>5#include <linux/btf.h>6#include <linux/btf_ids.h>7#include <linux/dcache.h>8#include <linux/fs.h>9#include <linux/fsnotify.h>10#include <linux/file.h>11#include <linux/kernfs.h>12#include <linux/mm.h>13#include <linux/xattr.h>1415__bpf_kfunc_start_defs();1617/**18* bpf_get_task_exe_file - get a reference on the exe_file struct file member of19* the mm_struct that is nested within the supplied20* task_struct21* @task: task_struct of which the nested mm_struct exe_file member to get a22* reference on23*24* Get a reference on the exe_file struct file member field of the mm_struct25* nested within the supplied *task*. The referenced file pointer acquired by26* this BPF kfunc must be released using bpf_put_file(). Failing to call27* bpf_put_file() on the returned referenced struct file pointer that has been28* acquired by this BPF kfunc will result in the BPF program being rejected by29* the BPF verifier.30*31* This BPF kfunc may only be called from BPF LSM programs.32*33* Internally, this BPF kfunc leans on get_task_exe_file(), such that calling34* bpf_get_task_exe_file() would be analogous to calling get_task_exe_file()35* directly in kernel context.36*37* Return: A referenced struct file pointer to the exe_file member of the38* mm_struct that is nested within the supplied *task*. On error, NULL is39* returned.40*/41__bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task)42{43return get_task_exe_file(task);44}4546/**47* bpf_put_file - put a reference on the supplied file48* @file: file to put a reference on49*50* Put a reference on the supplied *file*. Only referenced file pointers may be51* passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or52* any other arbitrary pointer for that matter, will result in the BPF program53* being rejected by the BPF verifier.54*55* This BPF kfunc may only be called from BPF LSM programs.56*/57__bpf_kfunc void bpf_put_file(struct file *file)58{59fput(file);60}6162/**63* bpf_path_d_path - resolve the pathname for the supplied path64* @path: path to resolve the pathname for65* @buf: buffer to return the resolved pathname in66* @buf__sz: length of the supplied buffer67*68* Resolve the pathname for the supplied *path* and store it in *buf*. This BPF69* kfunc is the safer variant of the legacy bpf_d_path() helper and should be70* used in place of bpf_d_path() whenever possible.71*72* This BPF kfunc may only be called from BPF LSM programs.73*74* Return: A positive integer corresponding to the length of the resolved75* pathname in *buf*, including the NUL termination character. On error, a76* negative integer is returned.77*/78__bpf_kfunc int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz)79{80int len;81char *ret;8283if (!buf__sz)84return -EINVAL;8586ret = d_path(path, buf, buf__sz);87if (IS_ERR(ret))88return PTR_ERR(ret);8990len = buf + buf__sz - ret;91memmove(buf, ret, len);92return len;93}9495static bool match_security_bpf_prefix(const char *name__str)96{97return !strncmp(name__str, XATTR_NAME_BPF_LSM, XATTR_NAME_BPF_LSM_LEN);98}99100static int bpf_xattr_read_permission(const char *name, struct inode *inode)101{102if (WARN_ON(!inode))103return -EINVAL;104105/* Allow reading xattr with user. and security.bpf. prefix */106if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&107!match_security_bpf_prefix(name))108return -EPERM;109110return inode_permission(&nop_mnt_idmap, inode, MAY_READ);111}112113/**114* bpf_get_dentry_xattr - get xattr of a dentry115* @dentry: dentry to get xattr from116* @name__str: name of the xattr117* @value_p: output buffer of the xattr value118*119* Get xattr *name__str* of *dentry* and store the output in *value_ptr*.120*121* For security reasons, only *name__str* with prefixes "user." or122* "security.bpf." are allowed.123*124* Return: length of the xattr value on success, a negative value on error.125*/126__bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str,127struct bpf_dynptr *value_p)128{129struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;130struct inode *inode = d_inode(dentry);131u32 value_len;132void *value;133int ret;134135value_len = __bpf_dynptr_size(value_ptr);136value = __bpf_dynptr_data_rw(value_ptr, value_len);137if (!value)138return -EINVAL;139140ret = bpf_xattr_read_permission(name__str, inode);141if (ret)142return ret;143return __vfs_getxattr(dentry, inode, name__str, value, value_len);144}145146/**147* bpf_get_file_xattr - get xattr of a file148* @file: file to get xattr from149* @name__str: name of the xattr150* @value_p: output buffer of the xattr value151*152* Get xattr *name__str* of *file* and store the output in *value_ptr*.153*154* For security reasons, only *name__str* with prefixes "user." or155* "security.bpf." are allowed.156*157* Return: length of the xattr value on success, a negative value on error.158*/159__bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,160struct bpf_dynptr *value_p)161{162struct dentry *dentry;163164dentry = file_dentry(file);165return bpf_get_dentry_xattr(dentry, name__str, value_p);166}167168__bpf_kfunc_end_defs();169170static int bpf_xattr_write_permission(const char *name, struct inode *inode)171{172if (WARN_ON(!inode))173return -EINVAL;174175/* Only allow setting and removing security.bpf. xattrs */176if (!match_security_bpf_prefix(name))177return -EPERM;178179return inode_permission(&nop_mnt_idmap, inode, MAY_WRITE);180}181182/**183* bpf_set_dentry_xattr_locked - set a xattr of a dentry184* @dentry: dentry to get xattr from185* @name__str: name of the xattr186* @value_p: xattr value187* @flags: flags to pass into filesystem operations188*189* Set xattr *name__str* of *dentry* to the value in *value_ptr*.190*191* For security reasons, only *name__str* with prefix "security.bpf."192* is allowed.193*194* The caller already locked dentry->d_inode.195*196* Return: 0 on success, a negative value on error.197*/198int bpf_set_dentry_xattr_locked(struct dentry *dentry, const char *name__str,199const struct bpf_dynptr *value_p, int flags)200{201202struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;203struct inode *inode = d_inode(dentry);204const void *value;205u32 value_len;206int ret;207208value_len = __bpf_dynptr_size(value_ptr);209value = __bpf_dynptr_data(value_ptr, value_len);210if (!value)211return -EINVAL;212213ret = bpf_xattr_write_permission(name__str, inode);214if (ret)215return ret;216217ret = __vfs_setxattr(&nop_mnt_idmap, dentry, inode, name__str,218value, value_len, flags);219if (!ret) {220fsnotify_xattr(dentry);221222/* This xattr is set by BPF LSM, so we do not call223* security_inode_post_setxattr. Otherwise, we would224* risk deadlocks by calling back to the same kfunc.225*226* This is the same as security_inode_setsecurity().227*/228}229return ret;230}231232/**233* bpf_remove_dentry_xattr_locked - remove a xattr of a dentry234* @dentry: dentry to get xattr from235* @name__str: name of the xattr236*237* Rmove xattr *name__str* of *dentry*.238*239* For security reasons, only *name__str* with prefix "security.bpf."240* is allowed.241*242* The caller already locked dentry->d_inode.243*244* Return: 0 on success, a negative value on error.245*/246int bpf_remove_dentry_xattr_locked(struct dentry *dentry, const char *name__str)247{248struct inode *inode = d_inode(dentry);249int ret;250251ret = bpf_xattr_write_permission(name__str, inode);252if (ret)253return ret;254255ret = __vfs_removexattr(&nop_mnt_idmap, dentry, name__str);256if (!ret) {257fsnotify_xattr(dentry);258259/* This xattr is removed by BPF LSM, so we do not call260* security_inode_post_removexattr. Otherwise, we would261* risk deadlocks by calling back to the same kfunc.262*/263}264return ret;265}266267__bpf_kfunc_start_defs();268269/**270* bpf_set_dentry_xattr - set a xattr of a dentry271* @dentry: dentry to get xattr from272* @name__str: name of the xattr273* @value_p: xattr value274* @flags: flags to pass into filesystem operations275*276* Set xattr *name__str* of *dentry* to the value in *value_ptr*.277*278* For security reasons, only *name__str* with prefix "security.bpf."279* is allowed.280*281* The caller has not locked dentry->d_inode.282*283* Return: 0 on success, a negative value on error.284*/285__bpf_kfunc int bpf_set_dentry_xattr(struct dentry *dentry, const char *name__str,286const struct bpf_dynptr *value_p, int flags)287{288struct inode *inode = d_inode(dentry);289int ret;290291inode_lock(inode);292ret = bpf_set_dentry_xattr_locked(dentry, name__str, value_p, flags);293inode_unlock(inode);294return ret;295}296297/**298* bpf_remove_dentry_xattr - remove a xattr of a dentry299* @dentry: dentry to get xattr from300* @name__str: name of the xattr301*302* Rmove xattr *name__str* of *dentry*.303*304* For security reasons, only *name__str* with prefix "security.bpf."305* is allowed.306*307* The caller has not locked dentry->d_inode.308*309* Return: 0 on success, a negative value on error.310*/311__bpf_kfunc int bpf_remove_dentry_xattr(struct dentry *dentry, const char *name__str)312{313struct inode *inode = d_inode(dentry);314int ret;315316inode_lock(inode);317ret = bpf_remove_dentry_xattr_locked(dentry, name__str);318inode_unlock(inode);319return ret;320}321322#ifdef CONFIG_CGROUPS323/**324* bpf_cgroup_read_xattr - read xattr of a cgroup's node in cgroupfs325* @cgroup: cgroup to get xattr from326* @name__str: name of the xattr327* @value_p: output buffer of the xattr value328*329* Get xattr *name__str* of *cgroup* and store the output in *value_ptr*.330*331* For security reasons, only *name__str* with prefix "user." is allowed.332*333* Return: length of the xattr value on success, a negative value on error.334*/335__bpf_kfunc int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__str,336struct bpf_dynptr *value_p)337{338struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;339u32 value_len;340void *value;341342/* Only allow reading "user.*" xattrs */343if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))344return -EPERM;345346value_len = __bpf_dynptr_size(value_ptr);347value = __bpf_dynptr_data_rw(value_ptr, value_len);348if (!value)349return -EINVAL;350351return kernfs_xattr_get(cgroup->kn, name__str, value, value_len);352}353#endif /* CONFIG_CGROUPS */354355__bpf_kfunc_end_defs();356357BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)358BTF_ID_FLAGS(func, bpf_get_task_exe_file, KF_ACQUIRE | KF_RET_NULL)359BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)360BTF_ID_FLAGS(func, bpf_path_d_path)361BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE)362BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE)363BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE)364BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE)365BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)366367static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)368{369if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||370prog->type == BPF_PROG_TYPE_LSM)371return 0;372return -EACCES;373}374375/* bpf_[set|remove]_dentry_xattr.* hooks have KF_SLEEPABLE, so they are only376* available to sleepable hooks with dentry arguments.377*378* Setting and removing xattr requires exclusive lock on dentry->d_inode.379* Some hooks already locked d_inode, while some hooks have not locked380* d_inode. Therefore, we need different kfuncs for different hooks.381* Specifically, hooks in the following list (d_inode_locked_hooks)382* should call bpf_[set|remove]_dentry_xattr_locked; while other hooks383* should call bpf_[set|remove]_dentry_xattr.384*/385BTF_SET_START(d_inode_locked_hooks)386BTF_ID(func, bpf_lsm_inode_post_removexattr)387BTF_ID(func, bpf_lsm_inode_post_setattr)388BTF_ID(func, bpf_lsm_inode_post_setxattr)389BTF_ID(func, bpf_lsm_inode_removexattr)390BTF_ID(func, bpf_lsm_inode_rmdir)391BTF_ID(func, bpf_lsm_inode_setattr)392BTF_ID(func, bpf_lsm_inode_setxattr)393BTF_ID(func, bpf_lsm_inode_unlink)394#ifdef CONFIG_SECURITY_PATH395BTF_ID(func, bpf_lsm_path_unlink)396BTF_ID(func, bpf_lsm_path_rmdir)397#endif /* CONFIG_SECURITY_PATH */398BTF_SET_END(d_inode_locked_hooks)399400bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog)401{402return btf_id_set_contains(&d_inode_locked_hooks, prog->aux->attach_btf_id);403}404405static const struct btf_kfunc_id_set bpf_fs_kfunc_set = {406.owner = THIS_MODULE,407.set = &bpf_fs_kfunc_set_ids,408.filter = bpf_fs_kfuncs_filter,409};410411static int __init bpf_fs_kfuncs_init(void)412{413return register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set);414}415416late_initcall(bpf_fs_kfuncs_init);417418419