// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024 Google LLC. */

#include <linux/binfmt_misc.h>
#include <linux/bpf.h>
#include <linux/bpf_lsm.h>
#include <linux/btf.h>
#include <linux/btf_ids.h>
#include <linux/dcache.h>
#include <linux/fs.h>
#include <linux/fsnotify.h>
#include <linux/file.h>
#include <linux/kernfs.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/xattr.h>

__bpf_kfunc_start_defs();

/**
 * bpf_get_task_exe_file - get a reference on the exe_file struct file member of
 *                         the mm_struct that is nested within the supplied
 *                         task_struct
 * @task: task_struct of which the nested mm_struct exe_file member to get a
 * reference on
 *
 * Get a reference on the exe_file struct file member field of the mm_struct
 * nested within the supplied *task*. The referenced file pointer acquired by
 * this BPF kfunc must be released using bpf_put_file(). Failing to call
 * bpf_put_file() on the returned referenced struct file pointer that has been
 * acquired by this BPF kfunc will result in the BPF program being rejected by
 * the BPF verifier.
 *
 * This BPF kfunc may only be called from BPF LSM programs.
 *
 * Internally, this BPF kfunc leans on get_task_exe_file(), such that calling
 * bpf_get_task_exe_file() would be analogous to calling get_task_exe_file()
 * directly in kernel context.
 *
 * Return: A referenced struct file pointer to the exe_file member of the
 * mm_struct that is nested within the supplied *task*. On error, NULL is
 * returned.
 */
__bpf_kfunc struct file *bpf_get_task_exe_file(struct task_struct *task)
{
	return get_task_exe_file(task);
}

/**
 * bpf_put_file - put a reference on the supplied file
 * @file: file to put a reference on
 *
 * Put a reference on the supplied *file*. Only referenced file pointers may be
 * passed to this BPF kfunc. Attempting to pass an unreferenced file pointer, or
 * any other arbitrary pointer for that matter, will result in the BPF program
 * being rejected by the BPF verifier.
 *
 * This BPF kfunc may only be called from BPF LSM programs.
 */
__bpf_kfunc void bpf_put_file(struct file *file)
{
	fput(file);
}

/**
 * bpf_path_d_path - resolve the pathname for the supplied path
 * @path: path to resolve the pathname for
 * @buf: buffer to return the resolved pathname in
 * @buf__sz: length of the supplied buffer
 *
 * Resolve the pathname for the supplied *path* and store it in *buf*. This BPF
 * kfunc is the safer variant of the legacy bpf_d_path() helper and should be
 * used in place of bpf_d_path() whenever possible.
 *
 * This BPF kfunc may only be called from BPF LSM programs.
 *
 * Return: A positive integer corresponding to the length of the resolved
 * pathname in *buf*, including the NUL termination character. On error, a
 * negative integer is returned.
 */
__bpf_kfunc int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz)
{
	int len;
	char *ret;

	if (!buf__sz)
		return -EINVAL;

	ret = d_path(path, buf, buf__sz);
	if (IS_ERR(ret))
		return PTR_ERR(ret);

	len = buf + buf__sz - ret;
	memmove(buf, ret, len);
	return len;
}

static bool match_security_bpf_prefix(const char *name__str)
{
	return !strncmp(name__str, XATTR_NAME_BPF_LSM, XATTR_NAME_BPF_LSM_LEN);
}

static int bpf_xattr_read_permission(const char *name, struct inode *inode)
{
	if (!inode)
		return -EINVAL;

	/* Allow reading xattr with user. and security.bpf. prefix */
	if (strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
	    !match_security_bpf_prefix(name))
		return -EPERM;

	return inode_permission(&nop_mnt_idmap, inode, MAY_READ);
}

/**
 * bpf_get_dentry_xattr - get xattr of a dentry
 * @dentry: dentry to get xattr from
 * @name__str: name of the xattr
 * @value_p: output buffer of the xattr value
 *
 * Get xattr *name__str* of *dentry* and store the output in *value_ptr*.
 *
 * For security reasons, only *name__str* with prefixes "user." or
 * "security.bpf." are allowed.
 *
 * Return: length of the xattr value on success, a negative value on error.
 */
__bpf_kfunc int bpf_get_dentry_xattr(struct dentry *dentry, const char *name__str,
				     struct bpf_dynptr *value_p)
{
	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
	struct inode *inode = d_inode(dentry);
	u32 value_len;
	void *value;
	int ret;

	value_len = __bpf_dynptr_size(value_ptr);
	value = __bpf_dynptr_data_rw(value_ptr, value_len);
	if (!value)
		return -EINVAL;

	ret = bpf_xattr_read_permission(name__str, inode);
	if (ret)
		return ret;
	return __vfs_getxattr(dentry, inode, name__str, value, value_len);
}

/**
 * bpf_get_file_xattr - get xattr of a file
 * @file: file to get xattr from
 * @name__str: name of the xattr
 * @value_p: output buffer of the xattr value
 *
 * Get xattr *name__str* of *file* and store the output in *value_ptr*.
 *
 * For security reasons, only *name__str* with prefixes "user." or
 * "security.bpf." are allowed.
 *
 * Return: length of the xattr value on success, a negative value on error.
 */
__bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
				   struct bpf_dynptr *value_p)
{
	struct dentry *dentry;

	dentry = file_dentry(file);
	return bpf_get_dentry_xattr(dentry, name__str, value_p);
}

__bpf_kfunc_end_defs();

static int bpf_xattr_write_permission(const char *name, struct inode *inode)
{
	if (!inode)
		return -EINVAL;

	/* Only allow setting and removing security.bpf. xattrs */
	if (!match_security_bpf_prefix(name))
		return -EPERM;

	return inode_permission(&nop_mnt_idmap, inode, MAY_WRITE);
}

/**
 * bpf_set_dentry_xattr_locked - set a xattr of a dentry
 * @dentry: dentry to get xattr from
 * @name__str: name of the xattr
 * @value_p: xattr value
 * @flags: flags to pass into filesystem operations
 *
 * Set xattr *name__str* of *dentry* to the value in *value_ptr*.
 *
 * For security reasons, only *name__str* with prefix "security.bpf."
 * is allowed.
 *
 * The caller already locked dentry->d_inode.
 *
 * Return: 0 on success, a negative value on error.
 */
int bpf_set_dentry_xattr_locked(struct dentry *dentry, const char *name__str,
				const struct bpf_dynptr *value_p, int flags)
{

	const struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
	struct inode *inode = d_inode(dentry);
	const void *value;
	u32 value_len;
	int ret;

	value_len = __bpf_dynptr_size(value_ptr);
	value = __bpf_dynptr_data(value_ptr, value_len);
	if (!value)
		return -EINVAL;

	ret = bpf_xattr_write_permission(name__str, inode);
	if (ret)
		return ret;

	ret = __vfs_setxattr(&nop_mnt_idmap, dentry, inode, name__str,
			     value, value_len, flags);
	if (!ret) {
		fsnotify_xattr(dentry);

		/* This xattr is set by BPF LSM, so we do not call
		 * security_inode_post_setxattr. Otherwise, we would
		 * risk deadlocks by calling back to the same kfunc.
		 *
		 * This is the same as security_inode_setsecurity().
		 */
	}
	return ret;
}

/**
 * bpf_remove_dentry_xattr_locked - remove a xattr of a dentry
 * @dentry: dentry to get xattr from
 * @name__str: name of the xattr
 *
 * Rmove xattr *name__str* of *dentry*.
 *
 * For security reasons, only *name__str* with prefix "security.bpf."
 * is allowed.
 *
 * The caller already locked dentry->d_inode.
 *
 * Return: 0 on success, a negative value on error.
 */
int bpf_remove_dentry_xattr_locked(struct dentry *dentry, const char *name__str)
{
	struct inode *inode = d_inode(dentry);
	int ret;

	ret = bpf_xattr_write_permission(name__str, inode);
	if (ret)
		return ret;

	ret = __vfs_removexattr(&nop_mnt_idmap, dentry, name__str);
	if (!ret) {
		fsnotify_xattr(dentry);

		/* This xattr is removed by BPF LSM, so we do not call
		 * security_inode_post_removexattr. Otherwise, we would
		 * risk deadlocks by calling back to the same kfunc.
		 */
	}
	return ret;
}

__bpf_kfunc_start_defs();

/**
 * bpf_set_dentry_xattr - set a xattr of a dentry
 * @dentry: dentry to get xattr from
 * @name__str: name of the xattr
 * @value_p: xattr value
 * @flags: flags to pass into filesystem operations
 *
 * Set xattr *name__str* of *dentry* to the value in *value_ptr*.
 *
 * For security reasons, only *name__str* with prefix "security.bpf."
 * is allowed.
 *
 * The caller has not locked dentry->d_inode.
 *
 * Return: 0 on success, a negative value on error.
 */
__bpf_kfunc int bpf_set_dentry_xattr(struct dentry *dentry, const char *name__str,
				     const struct bpf_dynptr *value_p, int flags)
{
	struct inode *inode = d_inode(dentry);
	int ret;

	if (!inode)
		return -EINVAL;

	inode_lock(inode);
	ret = bpf_set_dentry_xattr_locked(dentry, name__str, value_p, flags);
	inode_unlock(inode);
	return ret;
}

/**
 * bpf_remove_dentry_xattr - remove a xattr of a dentry
 * @dentry: dentry to get xattr from
 * @name__str: name of the xattr
 *
 * Rmove xattr *name__str* of *dentry*.
 *
 * For security reasons, only *name__str* with prefix "security.bpf."
 * is allowed.
 *
 * The caller has not locked dentry->d_inode.
 *
 * Return: 0 on success, a negative value on error.
 */
__bpf_kfunc int bpf_remove_dentry_xattr(struct dentry *dentry, const char *name__str)
{
	struct inode *inode = d_inode(dentry);
	int ret;

	if (!inode)
		return -EINVAL;

	inode_lock(inode);
	ret = bpf_remove_dentry_xattr_locked(dentry, name__str);
	inode_unlock(inode);
	return ret;
}

#ifdef CONFIG_CGROUPS
/**
 * bpf_cgroup_read_xattr - read xattr of a cgroup's node in cgroupfs
 * @cgroup: cgroup to get xattr from
 * @name__str: name of the xattr
 * @value_p: output buffer of the xattr value
 *
 * Get xattr *name__str* of *cgroup* and store the output in *value_ptr*.
 *
 * For security reasons, only *name__str* with prefix "user." is allowed.
 *
 * Return: length of the xattr value on success, a negative value on error.
 */
__bpf_kfunc int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__str,
					struct bpf_dynptr *value_p)
{
	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
	u32 value_len;
	void *value;

	/* Only allow reading "user.*" xattrs */
	if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
		return -EPERM;

	value_len = __bpf_dynptr_size(value_ptr);
	value = __bpf_dynptr_data_rw(value_ptr, value_len);
	if (!value)
		return -EINVAL;

	return kernfs_xattr_get(cgroup->kn, name__str, value, value_len);
}
#endif /* CONFIG_CGROUPS */

#ifdef CONFIG_NET
/**
 * bpf_sock_read_xattr - read xattr of a socket's inode in sockfs
 * @sock: socket to get xattr from
 * @name__str: name of the xattr
 * @value_p: output buffer of the xattr value
 *
 * Get xattr *name__str* of *sock* and store the output in *value_p*.
 *
 * For security reasons, only *name__str* with prefix "user." is allowed.
 *
 * Return: length of the xattr value on success, a negative value on error.
 */
__bpf_kfunc int bpf_sock_read_xattr(struct socket *sock, const char *name__str,
				    struct bpf_dynptr *value_p)
{
	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
	u32 value_len;
	void *value;

	/* Only allow reading "user.*" xattrs */
	if (strncmp(name__str, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
		return -EPERM;

	value_len = __bpf_dynptr_size(value_ptr);
	value = __bpf_dynptr_data_rw(value_ptr, value_len);
	if (!value)
		return -EINVAL;

	return sock_read_xattr(sock, name__str, value, value_len);
}
#endif /* CONFIG_NET */

/**
 * bpf_real_data_inode - get the real inode hosting a file's data
 * @file: file to resolve
 *
 * Resolve @file to the inode that hosts its data. For a regular file on a
 * union/overlay filesystem this is the underlying (upper or lower) inode that
 * stores the data, not the overlay inode.
 *
 * Data resolution only applies to regular files. For a non-regular file (e.g.
 * a device node, fifo or socket) on a union/overlay filesystem the overlay
 * inode itself is returned; for any file on a non-union filesystem the inode
 * attached to @file is returned.
 *
 * Return: The inode hosting @file's data, or NULL.
 */
__bpf_kfunc struct inode *bpf_real_data_inode(struct file *file)
{
	return d_real_inode(file_dentry(file));
}

__bpf_kfunc_end_defs();

BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)
BTF_ID_FLAGS(func, bpf_get_task_exe_file, KF_ACQUIRE | KF_RET_NULL)
BTF_ID_FLAGS(func, bpf_put_file, KF_RELEASE)
BTF_ID_FLAGS(func, bpf_path_d_path)
BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE)
BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE)
BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE)
BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE)
BTF_ID_FLAGS(func, bpf_real_data_inode, KF_SLEEPABLE | KF_RET_NULL)
#ifdef CONFIG_NET
BTF_ID_FLAGS(func, bpf_sock_read_xattr, KF_RCU)
#endif
BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)

/* Side-effecting kfuncs that stay exclusive to LSM programs. */
BTF_SET_START(bpf_fs_kfunc_lsm_only_ids)
BTF_ID(func, bpf_set_dentry_xattr)
BTF_ID(func, bpf_remove_dentry_xattr)
BTF_SET_END(bpf_fs_kfunc_lsm_only_ids)

static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
{
	if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id))
		return 0;
	if (prog->type == BPF_PROG_TYPE_LSM)
		return 0;
	if (prog->type != BPF_PROG_TYPE_STRUCT_OPS)
		return -EACCES;
	/* ->st_ops is unset during the cfg pass; enforced once it is set. */
	if (!prog->aux->st_ops)
		return 0;
	if (bpf_prog_is_binfmt_misc_ops(prog) &&
	    !btf_id_set_contains(&bpf_fs_kfunc_lsm_only_ids, kfunc_id))
		return 0;
	return -EACCES;
}

/* bpf_[set|remove]_dentry_xattr.* hooks have KF_SLEEPABLE, so they are only
 * available to sleepable hooks with dentry arguments.
 *
 * Setting and removing xattr requires exclusive lock on dentry->d_inode.
 * Some hooks already locked d_inode, while some hooks have not locked
 * d_inode. Therefore, we need different kfuncs for different hooks.
 * Specifically, hooks in the following list (d_inode_locked_hooks)
 * should call bpf_[set|remove]_dentry_xattr_locked; while other hooks
 * should call bpf_[set|remove]_dentry_xattr.
 */
BTF_SET_START(d_inode_locked_hooks)
BTF_ID(func, bpf_lsm_inode_post_removexattr)
BTF_ID(func, bpf_lsm_inode_post_setattr)
BTF_ID(func, bpf_lsm_inode_post_setxattr)
BTF_ID(func, bpf_lsm_inode_removexattr)
BTF_ID(func, bpf_lsm_inode_rmdir)
BTF_ID(func, bpf_lsm_inode_setattr)
BTF_ID(func, bpf_lsm_inode_setxattr)
BTF_ID(func, bpf_lsm_inode_unlink)
#ifdef CONFIG_SECURITY_PATH
BTF_ID(func, bpf_lsm_path_unlink)
BTF_ID(func, bpf_lsm_path_rmdir)
#endif /* CONFIG_SECURITY_PATH */
BTF_SET_END(d_inode_locked_hooks)

bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog)
{
	return btf_id_set_contains(&d_inode_locked_hooks, prog->aux->attach_btf_id);
}

static const struct btf_kfunc_id_set bpf_fs_kfunc_set = {
	.owner = THIS_MODULE,
	.set = &bpf_fs_kfunc_set_ids,
	.filter = bpf_fs_kfuncs_filter,
};

static int __init bpf_fs_kfuncs_init(void)
{
	int ret;

	ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, &bpf_fs_kfunc_set);
	if (ret || !IS_ENABLED(CONFIG_BINFMT_MISC_BPF))
		return ret;
	return register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS,
					 &bpf_fs_kfunc_set);
}

late_initcall(bpf_fs_kfuncs_init);
