From: Martin KaFai Lau <kafai@fb.com>
To: <netdev@vger.kernel.org>
Cc: Alexei Starovoitov <ast@fb.com>,
Daniel Borkmann <daniel@iogearbox.net>, <kernel-team@fb.com>
Subject: [PATCH bpf-next v4 05/10] bpf: btf: Add BPF_BTF_LOAD command
Date: Tue, 17 Apr 2018 13:42:38 -0700 [thread overview]
Message-ID: <20180417204243.4028831-6-kafai@fb.com> (raw)
In-Reply-To: <20180417204243.4028831-1-kafai@fb.com>
This patch adds a BPF_BTF_LOAD command which
1) loads and verifies the BTF (implemented in earlier patches)
2) returns a BTF fd to userspace. In the next patch, the
BTF fd can be specified during BPF_MAP_CREATE.
It currently limits to CAP_SYS_ADMIN.
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Alexei Starovoitov <ast@fb.com>
---
include/linux/btf.h | 4 +++
include/uapi/linux/bpf.h | 9 +++++++
kernel/bpf/btf.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
kernel/bpf/syscall.c | 17 ++++++++++++
4 files changed, 97 insertions(+)
diff --git a/include/linux/btf.h b/include/linux/btf.h
index d8bdab0280ba..a7c7072535ea 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -8,7 +8,11 @@
struct btf;
struct btf_type;
+union bpf_attr;
+void btf_put(struct btf *btf);
+int btf_new_fd(const union bpf_attr *attr);
+struct btf *btf_get_by_fd(int fd);
/* Figure out the size of a type_id. If type_id is a modifier
* (e.g. const), it will be resolved to find out the type with size.
*
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index c5ec89732a8d..c7d75f18521b 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -95,6 +95,7 @@ enum bpf_cmd {
BPF_OBJ_GET_INFO_BY_FD,
BPF_PROG_QUERY,
BPF_RAW_TRACEPOINT_OPEN,
+ BPF_BTF_LOAD,
};
enum bpf_map_type {
@@ -363,6 +364,14 @@ union bpf_attr {
__u64 name;
__u32 prog_fd;
} raw_tracepoint;
+
+ struct { /* anonymous struct for BPF_BTF_LOAD */
+ __aligned_u64 btf;
+ __aligned_u64 btf_log_buf;
+ __u32 btf_size;
+ __u32 btf_log_size;
+ __u32 btf_log_level;
+ };
} __attribute__((aligned(8)));
/* BPF helper function descriptions:
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 4703b26e34a9..ba088f02ed17 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -7,6 +7,8 @@
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/bpf_verifier.h>
@@ -190,6 +192,7 @@ struct btf {
u32 nr_types;
u32 types_size;
u32 data_size;
+ refcount_t refcnt;
};
enum verifier_phase {
@@ -607,6 +610,17 @@ static void btf_free(struct btf *btf)
kfree(btf);
}
+static void btf_get(struct btf *btf)
+{
+ refcount_inc(&btf->refcnt);
+}
+
+void btf_put(struct btf *btf)
+{
+ if (btf && refcount_dec_and_test(&btf->refcnt))
+ btf_free(btf);
+}
+
static int env_resolve_init(struct btf_verifier_env *env)
{
struct btf *btf = env->btf;
@@ -1990,6 +2004,7 @@ static struct btf *btf_parse(void __user *btf_data, u32 btf_data_size,
if (!err) {
btf_verifier_env_free(env);
+ btf_get(btf);
return btf;
}
@@ -2007,3 +2022,55 @@ void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj,
btf_type_ops(t)->seq_show(btf, t, type_id, obj, 0, m);
}
+
+static int btf_release(struct inode *inode, struct file *filp)
+{
+ btf_put(filp->private_data);
+ return 0;
+}
+
+static const struct file_operations btf_fops = {
+ .release = btf_release,
+};
+
+int btf_new_fd(const union bpf_attr *attr)
+{
+ struct btf *btf;
+ int fd;
+
+ btf = btf_parse(u64_to_user_ptr(attr->btf),
+ attr->btf_size, attr->btf_log_level,
+ u64_to_user_ptr(attr->btf_log_buf),
+ attr->btf_log_size);
+ if (IS_ERR(btf))
+ return PTR_ERR(btf);
+
+ fd = anon_inode_getfd("btf", &btf_fops, btf,
+ O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ btf_put(btf);
+
+ return fd;
+}
+
+struct btf *btf_get_by_fd(int fd)
+{
+ struct btf *btf;
+ struct fd f;
+
+ f = fdget(fd);
+
+ if (!f.file)
+ return ERR_PTR(-EBADF);
+
+ if (f.file->f_op != &btf_fops) {
+ fdput(f);
+ return ERR_PTR(-EINVAL);
+ }
+
+ btf = f.file->private_data;
+ btf_get(btf);
+ fdput(f);
+
+ return btf;
+}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4ca46df19c9a..cd8ebadc66eb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -11,6 +11,7 @@
*/
#include <linux/bpf.h>
#include <linux/bpf_trace.h>
+#include <linux/btf.h>
#include <linux/syscalls.h>
#include <linux/slab.h>
#include <linux/sched/signal.h>
@@ -2023,6 +2024,19 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
return err;
}
+#define BPF_BTF_LOAD_LAST_FIELD btf_log_level
+
+static int bpf_btf_load(const union bpf_attr *attr)
+{
+ if (CHECK_ATTR(BPF_BTF_LOAD))
+ return -EINVAL;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ return btf_new_fd(attr);
+}
+
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
{
union bpf_attr attr = {};
@@ -2103,6 +2117,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
case BPF_RAW_TRACEPOINT_OPEN:
err = bpf_raw_tracepoint_open(&attr);
break;
+ case BPF_BTF_LOAD:
+ err = bpf_btf_load(&attr);
+ break;
default:
err = -EINVAL;
break;
--
2.9.5
next prev parent reply other threads:[~2018-04-17 20:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-17 20:42 [PATCH bpf-next v4 00/10] BTF: BPF Type Format Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 01/10] bpf: btf: Introduce BPF Type Format (BTF) Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 02/10] bpf: btf: Validate type reference Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 03/10] bpf: btf: Check members of struct/union Martin KaFai Lau
2018-04-18 17:22 ` Jakub Kicinski
2018-04-18 18:01 ` Martin KaFai Lau
2018-04-18 18:30 ` Jakub Kicinski
2018-04-17 20:42 ` [PATCH bpf-next v4 04/10] bpf: btf: Add pretty print capability for data with BTF type info Martin KaFai Lau
2018-04-17 20:42 ` Martin KaFai Lau [this message]
2018-04-17 20:42 ` [PATCH bpf-next v4 06/10] bpf: btf: Add BPF_OBJ_GET_INFO_BY_FD support to BTF fd Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 07/10] bpf: btf: Add pretty print support to the basic arraymap Martin KaFai Lau
2018-04-18 15:20 ` Daniel Borkmann
2018-04-18 17:05 ` Jakub Kicinski
2018-04-18 17:46 ` Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 08/10] bpf: btf: Sync bpf.h and btf.h to tools/ Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 09/10] bpf: btf: Add BTF support to libbpf Martin KaFai Lau
2018-04-17 20:42 ` [PATCH bpf-next v4 10/10] bpf: btf: Add BTF tests Martin KaFai Lau
2018-04-18 20:36 ` [PATCH bpf-next v4 00/10] BTF: BPF Type Format Daniel Borkmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180417204243.4028831-6-kafai@fb.com \
--to=kafai@fb.com \
--cc=ast@fb.com \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox