#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_mount_opts *mnt_opts;
	struct bpf_token *token = NULL;
	struct user_namespace *userns;
	struct inode *inode;
	struct file *file;
	CLASS(fd, f)(attr->token_create.bpffs_fd);
	struct path path;
	struct super_block *sb;
	umode_t mode;
	int err, fd;

	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 */

	file = alloc_file_pseudo(inode, path.mnt, BPF_TOKEN_INODE_NAME, O_RDWR, &bpf_token_fops);
	if (IS_ERR(file)) {
		iput(inode);
		return PTR_ERR(file);
	}

	token = kzalloc(sizeof(*token), GFP_USER);
	if (!token) {
		err = -ENOMEM;
		goto out_file;
	}

	atomic64_set(&token->refcnt, 1);

	/* remember bpffs owning userns for future ns_capable() checks */
	token->userns = get_user_ns(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)
		goto out_token;

	fd = get_unused_fd_flags(O_CLOEXEC);
	if (fd < 0) {
		err = fd;
		goto out_token;
	}

	file->private_data = token;
	fd_install(fd, file);

	return fd;

out_token:
	bpf_token_free(token);
out_file:
	fput(file);
	return err;
}

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));
}
