// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include <linux/vmalloc.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/idr.h>
#include <linux/namei.h>
#include <linux/user_namespace.h>
#include <linux/security.h>

static bool bpf_ns_capable(struct user_namespace *ns, int cap)
{
	return ns_capable(ns, cap) || (cap != CAP_SYS_ADMIN && ns_capable(ns, CAP_SYS_ADMIN));
}

bool bpf_token_capable(const struct bpf_token *token, int cap)
{
	struct user_namespace *userns;

	/* BPF token allows ns_capable() level of capabilities */
	userns = token ? token->userns : &init_user_ns;
	if (!bpf_ns_capable(userns, cap))
		return false;
	if (token && security_bpf_token_capable(token, cap) < 0)
		return false;
	return true;
}

void bpf_token_inc(struct bpf_token *token)
{
	atomic64_inc(&token->refcnt);
}

static void bpf_token_free(struct bpf_token *token)
{
	security_bpf_token_free(token);
	put_user_ns(token->userns);
	kfree(token);
}

static void bpf_token_put_deferred(struct work_struct *work)
{
	struct bpf_token *token = container_of(work, struct bpf_token, work);

	bpf_token_free(token);
}

void bpf_token_put(struct bpf_token *token)
{
	if (!token)
		return;

	if (!atomic64_dec_and_test(&token->refcnt))
		return;

	INIT_WORK(&token->work, bpf_token_put_deferred);
	schedule_work(&token->work);
}

static int bpf_token_release(struct inode *inode, struct file *filp)
{
	struct bpf_token *token = filp->private_data;

	bpf_token_put(token);
	return 0;
}

static void bpf_token_show_fdinfo(struct seq_file *m, struct file *filp)
{
	struct bpf_token *token = filp->private_data;
	u64 mask;

	BUILD_BUG_ON(__MAX_BPF_CMD >= 64);
	mask = BIT_ULL(__MAX_BPF_CMD) - 1;
	if ((token->allowed_cmds & mask) == mask)
		seq_printf(m, "allowed_cmds:\tany\n");
	else
		seq_printf(m, "allowed_cmds:\t0x%llx\n", token->allowed_cmds);

	BUILD_BUG_ON(__MAX_BPF_MAP_TYPE >= 64);
	mask = BIT_ULL(__MAX_BPF_MAP_TYPE) - 1;
	if ((token->allowed_maps & mask) == mask)
		seq_printf(m, "allowed_maps:\tany\n");
	else
		seq_printf(m, "allowed_maps:\t0x%llx\n", token->allowed_maps);

	BUILD_BUG_ON(__MAX_BPF_PROG_TYPE >= 64);
	mask = BIT_ULL(__MAX_BPF_PROG_TYPE) - 1;
	if ((token->allowed_progs & mask) == mask)
		seq_printf(m, "allowed_progs:\tany\n");
	else
		seq_printf(m, "allowed_progs:\t0x%llx\n", token->allowed_progs);

	BUILD_BUG_ON(__MAX_BPF_ATTACH_TYPE >= 64);
	mask = BIT_ULL(__MAX_BPF_ATTACH_TYPE) - 1;
	if ((token->allowed_attachs & mask) == mask)
		seq_printf(m, "allowed_attachs:\tany\n");
	else
		seq_printf(m, "allowed_attachs:\t0x%llx\n", token->allowed_attachs);
}

#define BPF_TOKEN_INODE_NAME "bpf-token"

static const struct inode_operations bpf_token_iops = { };

const struct file_operations bpf_token_fops = {
	.release	= bpf_token_release,
	.show_fdinfo	= bpf_token_show_fdinfo,
};

int bpf_token_create(union bpf_attr *attr)
{
	struct bpf_token *token __free(kfree) = NULL;
	struct bpf_mount_opts *mnt_opts;
	struct user_namespace *userns;
	struct inode *inode;
	CLASS(fd, f)(attr->token_create.bpffs_fd);
	struct path path;
	struct super_block *sb;
	umode_t mode;
	int err;

	if (fd_empty(f))
		return -EBADF;

	path = fd_file(f)->f_path;
	sb = path.dentry->d_sb;

	if (path.dentry != sb->s_root)
		return -EINVAL;
	if (sb->s_op != &bpf_super_ops)
		return -EINVAL;
	err = path_permission(&path, MAY_ACCESS);
	if (err)
		return err;

	userns = sb->s_user_ns;
	/*
	 * Enforce that creators of BPF tokens are in the same user
	 * namespace as the BPF FS instance. This makes reasoning about
	 * permissions a lot easier and we can always relax this later.
	 */
	if (current_user_ns() != userns)
		return -EPERM;
	if (!ns_capable(userns, CAP_BPF))
		return -EPERM;

	/* Creating BPF token in init_user_ns doesn't make much sense. */
	if (current_user_ns() == &init_user_ns)
		return -EOPNOTSUPP;

	mnt_opts = sb->s_fs_info;
	if (mnt_opts->delegate_cmds == 0 &&
	    mnt_opts->delegate_maps == 0 &&
	    mnt_opts->delegate_progs == 0 &&
	    mnt_opts->delegate_attachs == 0)
		return -ENOENT; /* no BPF token delegation is set up */

	mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask());
	inode = bpf_get_inode(sb, NULL, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	inode->i_op = &bpf_token_iops;
	inode->i_fop = &bpf_token_fops;
	clear_nlink(inode); /* make sure it is unlinked */

	FD_PREPARE(fdf, O_CLOEXEC,
		   alloc_file_pseudo(inode, path.mnt, BPF_TOKEN_INODE_NAME,
				     O_RDWR, &bpf_token_fops));
	if (fdf.err)
		return fdf.err;

	token = kzalloc_obj(*token, GFP_USER);
	if (!token)
		return -ENOMEM;

	atomic64_set(&token->refcnt, 1);

	/* remember bpffs owning userns for future ns_capable() checks. */
	token->userns = userns;
	token->allowed_cmds = mnt_opts->delegate_cmds;
	token->allowed_maps = mnt_opts->delegate_maps;
	token->allowed_progs = mnt_opts->delegate_progs;
	token->allowed_attachs = mnt_opts->delegate_attachs;

	err = security_bpf_token_create(token, attr, &path);
	if (err)
		return err;

	get_user_ns(token->userns);
	fd_prepare_file(fdf)->private_data = no_free_ptr(token);
	return fd_publish(fdf);
}

int bpf_token_get_info_by_fd(struct bpf_token *token,
			     const union bpf_attr *attr,
			     union bpf_attr __user *uattr)
{
	struct bpf_token_info __user *uinfo = u64_to_user_ptr(attr->info.info);
	struct bpf_token_info info;
	u32 info_len = attr->info.info_len;

	info_len = min_t(u32, info_len, sizeof(info));
	memset(&info, 0, sizeof(info));

	info.allowed_cmds = token->allowed_cmds;
	info.allowed_maps = token->allowed_maps;
	info.allowed_progs = token->allowed_progs;
	info.allowed_attachs = token->allowed_attachs;

	if (copy_to_user(uinfo, &info, info_len) ||
	    put_user(info_len, &uattr->info.info_len))
		return -EFAULT;

	return 0;
}

struct bpf_token *bpf_token_get_from_fd(u32 ufd)
{
	CLASS(fd, f)(ufd);
	struct bpf_token *token;

	if (fd_empty(f))
		return ERR_PTR(-EBADF);
	if (fd_file(f)->f_op != &bpf_token_fops)
		return ERR_PTR(-EINVAL);

	token = fd_file(f)->private_data;
	bpf_token_inc(token);

	return token;
}

bool bpf_token_allow_cmd(const struct bpf_token *token, enum bpf_cmd cmd)
{
	if (!token)
		return false;
	if (!(token->allowed_cmds & BIT_ULL(cmd)))
		return false;
	return security_bpf_token_cmd(token, cmd) == 0;
}

bool bpf_token_allow_map_type(const struct bpf_token *token, enum bpf_map_type type)
{
	if (!token || type >= __MAX_BPF_MAP_TYPE)
		return false;

	return token->allowed_maps & BIT_ULL(type);
}

bool bpf_token_allow_prog_type(const struct bpf_token *token,
			       enum bpf_prog_type prog_type,
			       enum bpf_attach_type attach_type)
{
	if (!token || prog_type >= __MAX_BPF_PROG_TYPE || attach_type >= __MAX_BPF_ATTACH_TYPE)
		return false;

	return (token->allowed_progs & BIT_ULL(prog_type)) &&
	       (token->allowed_attachs & BIT_ULL(attach_type));
}
