// SPDX-License-Identifier: GPL-2.0-only
/*
* Minimal file system backend for holding eBPF maps and programs,
* used by bpf(2) object pinning.
*
* Authors:
*
* Daniel Borkmann <daniel@iogearbox.net>
*/
#include <linux/init.h>
#include <linux/magic.h>
#include <linux/major.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#include <linux/kdev_t.h>
#include <linux/filter.h>
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
#include <linux/kstrtox.h>
#include <linux/xattr.h>
#include <linux/security.h>
#include "preload/bpf_preload.h"
enum bpf_type {
BPF_TYPE_UNSPEC = 0,
BPF_TYPE_PROG,
BPF_TYPE_MAP,
BPF_TYPE_LINK,
};
struct bpf_fs_inode {
struct list_head xattrs;
struct simple_xattr_limits xlimits;
struct inode vfs_inode;
};
static inline struct bpf_fs_inode *BPF_FS_I(struct inode *inode)
{
return container_of(inode, struct bpf_fs_inode, vfs_inode);
}
static struct kmem_cache *bpf_fs_inode_cachep __ro_after_init;
static int bpf_fs_initxattrs(struct inode *inode,
const struct xattr *xattr_array, void *fs_info);
static ssize_t bpf_fs_listxattr(struct dentry *dentry, char *buf, size_t size);
static void *bpf_any_get(void *raw, enum bpf_type type)
{
switch (type) {
case BPF_TYPE_PROG:
bpf_prog_inc(raw);
break;
case BPF_TYPE_MAP:
bpf_map_inc_with_uref(raw);
break;
case BPF_TYPE_LINK:
bpf_link_inc(raw);
break;
default:
WARN_ON_ONCE(1);
break;
}
return raw;
}
static void bpf_any_put(void *raw, enum bpf_type type)
{
switch (type) {
case BPF_TYPE_PROG:
bpf_prog_put(raw);
break;
case BPF_TYPE_MAP:
bpf_map_put_with_uref(raw);
break;
case BPF_TYPE_LINK:
bpf_link_put(raw);
break;
default:
WARN_ON_ONCE(1);
break;
}
}
static void *