All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/10] eBPF support for cls_bpf
@ 2015-02-27 14:55 Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 01/10] ebpf: remove kernel test stubs Daniel Borkmann
                   ` (10 more replies)
  0 siblings, 11 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

This is the non-RFC version of my patchset posted before netdev01 [1]
conference. It contains a couple of eBPF cleanups and preparation
patches to get eBPF support into cls_bpf. The last patch adds the
actual support. I'll post the iproute2 parts after the kernel bits
are merged, an initial preview link to the code is mentioned in the
last patch.

Patch 4 and 5 were originally one patch, but I've split them into
two parts upon request as patch 4 only is also needed for Alexei's
tracing patches that go via tip tree.

Tested with tc and all in-kernel available test suites.

I have configured and built LLVM with --enable-experimental-targets=BPF
but as Alexei put it, the plan is to get rid of the experimental
status in future [2].

Thanks a lot!

  [1] http://thread.gmane.org/gmane.linux.network/350191
  [2] http://article.gmane.org/gmane.linux.kernel/1874969

Daniel Borkmann (10):
  ebpf: remove kernel test stubs
  ebpf: constify various function pointer structs
  ebpf: export BPF_PSEUDO_MAP_FD to uapi
  ebpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs
  ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code
  ebpf: add sched_cls_type and map it to sk_filter's verifier ops
  ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux
  x86: unexport set_memory_ro and set_memory_rw
  arm64: unexport set_memory_ro and set_memory_rw
  cls_bpf: add initial eBPF support for programmable classifiers

 arch/arm64/mm/pageattr.c     |   2 -
 arch/x86/mm/pageattr.c       |   2 -
 include/linux/bpf.h          |  38 +++++---
 include/linux/filter.h       |   6 +-
 include/uapi/linux/bpf.h     |   3 +
 include/uapi/linux/pkt_cls.h |   2 +
 kernel/bpf/Makefile          |   3 -
 kernel/bpf/arraymap.c        |   6 +-
 kernel/bpf/hashtab.c         |   6 +-
 kernel/bpf/helpers.c         |   6 +-
 kernel/bpf/syscall.c         |   9 +-
 kernel/bpf/test_stub.c       |  78 ----------------
 kernel/bpf/verifier.c        |  17 +++-
 net/core/filter.c            |  47 +++++-----
 net/sched/cls_bpf.c          | 206 ++++++++++++++++++++++++++++++++-----------
 samples/bpf/libbpf.h         |   4 +-
 samples/bpf/test_verifier.c  |   5 +-
 17 files changed, 243 insertions(+), 197 deletions(-)
 delete mode 100644 kernel/bpf/test_stub.c

-- 
1.9.3

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH net-next 01/10] ebpf: remove kernel test stubs
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 02/10] ebpf: constify various function pointer structs Daniel Borkmann
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

Now that we have BPF_PROG_TYPE_SOCKET_FILTER up and running, we can
remove the test stubs which were added to get the verifier suite up.

We can just let the test cases probe under socket filter type instead.
In the fill/spill test case, we cannot (yet) access fields from the
context (skb), but we may adapt that test case in future.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 kernel/bpf/Makefile         |  3 --
 kernel/bpf/test_stub.c      | 78 ---------------------------------------------
 samples/bpf/test_verifier.c |  5 +--
 3 files changed, 3 insertions(+), 83 deletions(-)
 delete mode 100644 kernel/bpf/test_stub.c

diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index a5ae60f..e6983be 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -1,5 +1,2 @@
 obj-y := core.o
 obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o hashtab.o arraymap.o helpers.o
-ifdef CONFIG_TEST_BPF
-obj-$(CONFIG_BPF_SYSCALL) += test_stub.o
-endif
diff --git a/kernel/bpf/test_stub.c b/kernel/bpf/test_stub.c
deleted file mode 100644
index 0ceae1e..0000000
--- a/kernel/bpf/test_stub.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/bpf.h>
-
-/* test stubs for BPF_MAP_TYPE_UNSPEC and for BPF_PROG_TYPE_UNSPEC
- * to be used by user space verifier testsuite
- */
-struct bpf_context {
-	u64 arg1;
-	u64 arg2;
-};
-
-static const struct bpf_func_proto *test_func_proto(enum bpf_func_id func_id)
-{
-	switch (func_id) {
-	case BPF_FUNC_map_lookup_elem:
-		return &bpf_map_lookup_elem_proto;
-	case BPF_FUNC_map_update_elem:
-		return &bpf_map_update_elem_proto;
-	case BPF_FUNC_map_delete_elem:
-		return &bpf_map_delete_elem_proto;
-	default:
-		return NULL;
-	}
-}
-
-static const struct bpf_context_access {
-	int size;
-	enum bpf_access_type type;
-} test_ctx_access[] = {
-	[offsetof(struct bpf_context, arg1)] = {
-		FIELD_SIZEOF(struct bpf_context, arg1),
-		BPF_READ
-	},
-	[offsetof(struct bpf_context, arg2)] = {
-		FIELD_SIZEOF(struct bpf_context, arg2),
-		BPF_READ
-	},
-};
-
-static bool test_is_valid_access(int off, int size, enum bpf_access_type type)
-{
-	const struct bpf_context_access *access;
-
-	if (off < 0 || off >= ARRAY_SIZE(test_ctx_access))
-		return false;
-
-	access = &test_ctx_access[off];
-	if (access->size == size && (access->type & type))
-		return true;
-
-	return false;
-}
-
-static struct bpf_verifier_ops test_ops = {
-	.get_func_proto = test_func_proto,
-	.is_valid_access = test_is_valid_access,
-};
-
-static struct bpf_prog_type_list tl_prog = {
-	.ops = &test_ops,
-	.type = BPF_PROG_TYPE_UNSPEC,
-};
-
-static int __init register_test_ops(void)
-{
-	bpf_register_prog_type(&tl_prog);
-	return 0;
-}
-late_initcall(register_test_ops);
diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c
index b96175e..7b56b59 100644
--- a/samples/bpf/test_verifier.c
+++ b/samples/bpf/test_verifier.c
@@ -288,7 +288,8 @@ static struct bpf_test tests[] = {
 			BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
 
 			/* should be able to access R0 = *(R2 + 8) */
-			BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8),
+			/* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
 			BPF_EXIT_INSN(),
 		},
 		.result = ACCEPT,
@@ -687,7 +688,7 @@ static int test(void)
 		}
 		printf("#%d %s ", i, tests[i].descr);
 
-		prog_fd = bpf_prog_load(BPF_PROG_TYPE_UNSPEC, prog,
+		prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog,
 					prog_len * sizeof(struct bpf_insn),
 					"GPL");
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 02/10] ebpf: constify various function pointer structs
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 01/10] ebpf: remove kernel test stubs Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 03/10] ebpf: export BPF_PSEUDO_MAP_FD to uapi Daniel Borkmann
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

We can move bpf_map_ops and bpf_verifier_ops and other structs into ro
section, bpf_map_type_list and bpf_prog_type_list into read mostly.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/linux/bpf.h   | 14 +++++++-------
 kernel/bpf/arraymap.c |  6 +++---
 kernel/bpf/hashtab.c  |  6 +++---
 kernel/bpf/helpers.c  |  6 +++---
 net/core/filter.c     |  6 +++---
 5 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index bbfceb7..7844686 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -32,13 +32,13 @@ struct bpf_map {
 	u32 key_size;
 	u32 value_size;
 	u32 max_entries;
-	struct bpf_map_ops *ops;
+	const struct bpf_map_ops *ops;
 	struct work_struct work;
 };
 
 struct bpf_map_type_list {
 	struct list_head list_node;
-	struct bpf_map_ops *ops;
+	const struct bpf_map_ops *ops;
 	enum bpf_map_type type;
 };
 
@@ -109,7 +109,7 @@ struct bpf_verifier_ops {
 
 struct bpf_prog_type_list {
 	struct list_head list_node;
-	struct bpf_verifier_ops *ops;
+	const struct bpf_verifier_ops *ops;
 	enum bpf_prog_type type;
 };
 
@@ -121,7 +121,7 @@ struct bpf_prog_aux {
 	atomic_t refcnt;
 	bool is_gpl_compatible;
 	enum bpf_prog_type prog_type;
-	struct bpf_verifier_ops *ops;
+	const struct bpf_verifier_ops *ops;
 	struct bpf_map **used_maps;
 	u32 used_map_cnt;
 	struct bpf_prog *prog;
@@ -138,8 +138,8 @@ struct bpf_prog *bpf_prog_get(u32 ufd);
 int bpf_check(struct bpf_prog *fp, union bpf_attr *attr);
 
 /* verifier prototypes for helper functions called from eBPF programs */
-extern struct bpf_func_proto bpf_map_lookup_elem_proto;
-extern struct bpf_func_proto bpf_map_update_elem_proto;
-extern struct bpf_func_proto bpf_map_delete_elem_proto;
+extern const struct bpf_func_proto bpf_map_lookup_elem_proto;
+extern const struct bpf_func_proto bpf_map_update_elem_proto;
+extern const struct bpf_func_proto bpf_map_delete_elem_proto;
 
 #endif /* _LINUX_BPF_H */
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 9eb4d8a..8a66165 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -134,7 +134,7 @@ static void array_map_free(struct bpf_map *map)
 	kvfree(array);
 }
 
-static struct bpf_map_ops array_ops = {
+static const struct bpf_map_ops array_ops = {
 	.map_alloc = array_map_alloc,
 	.map_free = array_map_free,
 	.map_get_next_key = array_map_get_next_key,
@@ -143,14 +143,14 @@ static struct bpf_map_ops array_ops = {
 	.map_delete_elem = array_map_delete_elem,
 };
 
-static struct bpf_map_type_list tl = {
+static struct bpf_map_type_list array_type __read_mostly = {
 	.ops = &array_ops,
 	.type = BPF_MAP_TYPE_ARRAY,
 };
 
 static int __init register_array_map(void)
 {
-	bpf_register_map_type(&tl);
+	bpf_register_map_type(&array_type);
 	return 0;
 }
 late_initcall(register_array_map);
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index b3ba436..83c209d 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -345,7 +345,7 @@ static void htab_map_free(struct bpf_map *map)
 	kfree(htab);
 }
 
-static struct bpf_map_ops htab_ops = {
+static const struct bpf_map_ops htab_ops = {
 	.map_alloc = htab_map_alloc,
 	.map_free = htab_map_free,
 	.map_get_next_key = htab_map_get_next_key,
@@ -354,14 +354,14 @@ static struct bpf_map_ops htab_ops = {
 	.map_delete_elem = htab_map_delete_elem,
 };
 
-static struct bpf_map_type_list tl = {
+static struct bpf_map_type_list htab_type __read_mostly = {
 	.ops = &htab_ops,
 	.type = BPF_MAP_TYPE_HASH,
 };
 
 static int __init register_htab_map(void)
 {
-	bpf_register_map_type(&tl);
+	bpf_register_map_type(&htab_type);
 	return 0;
 }
 late_initcall(register_htab_map);
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 9e3414d..a3c7701 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -41,7 +41,7 @@ static u64 bpf_map_lookup_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
 	return (unsigned long) value;
 }
 
-struct bpf_func_proto bpf_map_lookup_elem_proto = {
+const struct bpf_func_proto bpf_map_lookup_elem_proto = {
 	.func = bpf_map_lookup_elem,
 	.gpl_only = false,
 	.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
@@ -60,7 +60,7 @@ static u64 bpf_map_update_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
 	return map->ops->map_update_elem(map, key, value, r4);
 }
 
-struct bpf_func_proto bpf_map_update_elem_proto = {
+const struct bpf_func_proto bpf_map_update_elem_proto = {
 	.func = bpf_map_update_elem,
 	.gpl_only = false,
 	.ret_type = RET_INTEGER,
@@ -80,7 +80,7 @@ static u64 bpf_map_delete_elem(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
 	return map->ops->map_delete_elem(map, key);
 }
 
-struct bpf_func_proto bpf_map_delete_elem_proto = {
+const struct bpf_func_proto bpf_map_delete_elem_proto = {
 	.func = bpf_map_delete_elem,
 	.gpl_only = false,
 	.ret_type = RET_INTEGER,
diff --git a/net/core/filter.c b/net/core/filter.c
index f6bdc2b..6fe09e3 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1159,19 +1159,19 @@ static bool sock_filter_is_valid_access(int off, int size, enum bpf_access_type
 	return false;
 }
 
-static struct bpf_verifier_ops sock_filter_ops = {
+static const struct bpf_verifier_ops sock_filter_ops = {
 	.get_func_proto = sock_filter_func_proto,
 	.is_valid_access = sock_filter_is_valid_access,
 };
 
-static struct bpf_prog_type_list tl = {
+static struct bpf_prog_type_list sock_filter_type __read_mostly = {
 	.ops = &sock_filter_ops,
 	.type = BPF_PROG_TYPE_SOCKET_FILTER,
 };
 
 static int __init register_sock_filter_ops(void)
 {
-	bpf_register_prog_type(&tl);
+	bpf_register_prog_type(&sock_filter_type);
 	return 0;
 }
 late_initcall(register_sock_filter_ops);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 03/10] ebpf: export BPF_PSEUDO_MAP_FD to uapi
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 01/10] ebpf: remove kernel test stubs Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 02/10] ebpf: constify various function pointer structs Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 04/10] ebpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs Daniel Borkmann
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

We need to export BPF_PSEUDO_MAP_FD to user space, as it's used in the
ELF BPF loader where instructions are being loaded that need map fixups.

An initial stage loads all maps into the kernel, and later on replaces
related instructions in the eBPF blob with BPF_PSEUDO_MAP_FD as source
register and the actual fd as immediate value.

The kernel verifier recognizes this keyword and replaces the map fd with
a real pointer internally.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/linux/filter.h   | 2 --
 include/uapi/linux/bpf.h | 2 ++
 samples/bpf/libbpf.h     | 4 +++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index caac208..5e3863d 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -145,8 +145,6 @@ struct bpf_prog_aux;
 		.off   = 0,					\
 		.imm   = ((__u64) (IMM)) >> 32 })
 
-#define BPF_PSEUDO_MAP_FD	1
-
 /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
 #define BPF_LD_MAP_FD(DST, MAP_FD)				\
 	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 45da7ec..0248180 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -120,6 +120,8 @@ enum bpf_prog_type {
 	BPF_PROG_TYPE_SOCKET_FILTER,
 };
 
+#define BPF_PSEUDO_MAP_FD	1
+
 /* flags for BPF_MAP_UPDATE_ELEM command */
 #define BPF_ANY		0 /* create new element or update existing */
 #define BPF_NOEXIST	1 /* create new element if it didn't exist */
diff --git a/samples/bpf/libbpf.h b/samples/bpf/libbpf.h
index 58c5fe1..a6bb7e9 100644
--- a/samples/bpf/libbpf.h
+++ b/samples/bpf/libbpf.h
@@ -92,7 +92,9 @@ extern char bpf_log_buf[LOG_BUF_SIZE];
 		.off   = 0,					\
 		.imm   = ((__u64) (IMM)) >> 32 })
 
-#define BPF_PSEUDO_MAP_FD	1
+#ifndef BPF_PSEUDO_MAP_FD
+# define BPF_PSEUDO_MAP_FD	1
+#endif
 
 /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
 #define BPF_LD_MAP_FD(DST, MAP_FD)				\
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 04/10] ebpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (2 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 03/10] ebpf: export BPF_PSEUDO_MAP_FD to uapi Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 05/10] ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code Daniel Borkmann
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

Socket filter code and other subsystems with upcoming eBPF support should
not need to deal with the fact that we have CONFIG_BPF_SYSCALL defined or
not.

Having the bpf syscall as a config option is a nice thing and I'd expect
it to stay that way for expert users (I presume one day the default setting
of it might change, though), but code making use of it should not care if
it's actually enabled or not.

Instead, hide this via header files and let the rest deal with it.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/linux/bpf.h | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 7844686..9c45814 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -113,8 +113,6 @@ struct bpf_prog_type_list {
 	enum bpf_prog_type type;
 };
 
-void bpf_register_prog_type(struct bpf_prog_type_list *tl);
-
 struct bpf_prog;
 
 struct bpf_prog_aux {
@@ -129,11 +127,25 @@ struct bpf_prog_aux {
 };
 
 #ifdef CONFIG_BPF_SYSCALL
+void bpf_register_prog_type(struct bpf_prog_type_list *tl);
+
 void bpf_prog_put(struct bpf_prog *prog);
+struct bpf_prog *bpf_prog_get(u32 ufd);
 #else
-static inline void bpf_prog_put(struct bpf_prog *prog) {}
+static inline void bpf_register_prog_type(struct bpf_prog_type_list *tl)
+{
+}
+
+static inline struct bpf_prog *bpf_prog_get(u32 ufd)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void bpf_prog_put(struct bpf_prog *prog)
+{
+}
 #endif
-struct bpf_prog *bpf_prog_get(u32 ufd);
+
 /* verify correctness of eBPF program */
 int bpf_check(struct bpf_prog *fp, union bpf_attr *attr);
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 05/10] ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (3 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 04/10] ebpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 06/10] ebpf: add sched_cls_type and map it to sk_filter's verifier ops Daniel Borkmann
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

This gets rid of CONFIG_BPF_SYSCALL ifdefs in the socket filter code,
now that the BPF internal header can deal with it.

While going over it, I also changed eBPF related functions to a sk_filter
prefix to be more consistent with the rest of the file.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 net/core/filter.c | 36 ++++++++++++++----------------------
 1 file changed, 14 insertions(+), 22 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index 6fe09e3..7417212 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1093,7 +1093,6 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(sk_attach_filter);
 
-#ifdef CONFIG_BPF_SYSCALL
 int sk_attach_bpf(u32 ufd, struct sock *sk)
 {
 	struct sk_filter *fp, *old_fp;
@@ -1107,7 +1106,6 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
 		return PTR_ERR(prog);
 
 	if (prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) {
-		/* valid fd, but invalid program type */
 		bpf_prog_put(prog);
 		return -EINVAL;
 	}
@@ -1117,8 +1115,8 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
 		bpf_prog_put(prog);
 		return -ENOMEM;
 	}
-	fp->prog = prog;
 
+	fp->prog = prog;
 	atomic_set(&fp->refcnt, 0);
 
 	if (!sk_filter_charge(sk, fp)) {
@@ -1136,10 +1134,8 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
 	return 0;
 }
 
-/* allow socket filters to call
- * bpf_map_lookup_elem(), bpf_map_update_elem(), bpf_map_delete_elem()
- */
-static const struct bpf_func_proto *sock_filter_func_proto(enum bpf_func_id func_id)
+static const struct bpf_func_proto *
+sk_filter_func_proto(enum bpf_func_id func_id)
 {
 	switch (func_id) {
 	case BPF_FUNC_map_lookup_elem:
@@ -1153,34 +1149,30 @@ static const struct bpf_func_proto *sock_filter_func_proto(enum bpf_func_id func
 	}
 }
 
-static bool sock_filter_is_valid_access(int off, int size, enum bpf_access_type type)
+static bool sk_filter_is_valid_access(int off, int size,
+				      enum bpf_access_type type)
 {
 	/* skb fields cannot be accessed yet */
 	return false;
 }
 
-static const struct bpf_verifier_ops sock_filter_ops = {
-	.get_func_proto = sock_filter_func_proto,
-	.is_valid_access = sock_filter_is_valid_access,
+static const struct bpf_verifier_ops sk_filter_ops = {
+	.get_func_proto = sk_filter_func_proto,
+	.is_valid_access = sk_filter_is_valid_access,
 };
 
-static struct bpf_prog_type_list sock_filter_type __read_mostly = {
-	.ops = &sock_filter_ops,
+static struct bpf_prog_type_list sk_filter_type __read_mostly = {
+	.ops = &sk_filter_ops,
 	.type = BPF_PROG_TYPE_SOCKET_FILTER,
 };
 
-static int __init register_sock_filter_ops(void)
+static int __init register_sk_filter_ops(void)
 {
-	bpf_register_prog_type(&sock_filter_type);
+	bpf_register_prog_type(&sk_filter_type);
 	return 0;
 }
-late_initcall(register_sock_filter_ops);
-#else
-int sk_attach_bpf(u32 ufd, struct sock *sk)
-{
-	return -EOPNOTSUPP;
-}
-#endif
+late_initcall(register_sk_filter_ops);
+
 int sk_detach_filter(struct sock *sk)
 {
 	int ret = -ENOENT;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 06/10] ebpf: add sched_cls_type and map it to sk_filter's verifier ops
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (4 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 05/10] ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 07/10] ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux Daniel Borkmann
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

As discussed recently and at netconf/netdev01, we want to prevent making
bpf_verifier_ops registration available for modules, but have them at a
controlled place inside the kernel instead.

The reason for this is, that out-of-tree modules can go crazy and define
and register any verfifier ops they want, doing all sorts of crap, even
bypassing available GPLed eBPF helper functions. We don't want to offer
such a shiny playground, of course, but keep strict control to ourselves
inside the core kernel.

This also encourages us to design eBPF user helpers carefully and
generically, so they can be shared among various subsystems using eBPF.

For the eBPF traffic classifier (cls_bpf), it's a good start to share
the same helper facilities as we currently do in eBPF for socket filters.

That way, we have BPF_PROG_TYPE_SCHED_CLS look like it's own type, thus
one day if there's a good reason to diverge the set of helper functions
from the set available to socket filters, we keep ABI compatibility.

In future, we could place all bpf_prog_type_list at a central place,
perhaps.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/uapi/linux/bpf.h |  1 +
 kernel/bpf/verifier.c    | 15 +++++++++++++--
 net/core/filter.c        |  7 +++++++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0248180..3fa1af8 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -118,6 +118,7 @@ enum bpf_map_type {
 enum bpf_prog_type {
 	BPF_PROG_TYPE_UNSPEC,
 	BPF_PROG_TYPE_SOCKET_FILTER,
+	BPF_PROG_TYPE_SCHED_CLS,
 };
 
 #define BPF_PSEUDO_MAP_FD	1
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a28e09c..594d341 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1172,6 +1172,17 @@ static int check_ld_imm(struct verifier_env *env, struct bpf_insn *insn)
 	return 0;
 }
 
+static bool may_access_skb(enum bpf_prog_type type)
+{
+	switch (type) {
+	case BPF_PROG_TYPE_SOCKET_FILTER:
+	case BPF_PROG_TYPE_SCHED_CLS:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* verify safety of LD_ABS|LD_IND instructions:
  * - they can only appear in the programs where ctx == skb
  * - since they are wrappers of function calls, they scratch R1-R5 registers,
@@ -1194,8 +1205,8 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
 	struct reg_state *reg;
 	int i, err;
 
-	if (env->prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) {
-		verbose("BPF_LD_ABS|IND instructions are only allowed in socket filters\n");
+	if (!may_access_skb(env->prog->aux->prog_type)) {
+		verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n");
 		return -EINVAL;
 	}
 
diff --git a/net/core/filter.c b/net/core/filter.c
index 7417212..514d408 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1166,9 +1166,16 @@ static struct bpf_prog_type_list sk_filter_type __read_mostly = {
 	.type = BPF_PROG_TYPE_SOCKET_FILTER,
 };
 
+static struct bpf_prog_type_list sched_cls_type __read_mostly = {
+	.ops = &sk_filter_ops,
+	.type = BPF_PROG_TYPE_SCHED_CLS,
+};
+
 static int __init register_sk_filter_ops(void)
 {
 	bpf_register_prog_type(&sk_filter_type);
+	bpf_register_prog_type(&sched_cls_type);
+
 	return 0;
 }
 late_initcall(register_sk_filter_ops);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 07/10] ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (5 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 06/10] ebpf: add sched_cls_type and map it to sk_filter's verifier ops Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 08/10] x86: unexport set_memory_ro and set_memory_rw Daniel Borkmann
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann

is_gpl_compatible and prog_type should be moved directly into bpf_prog
as they stay immutable during bpf_prog's lifetime, are core attributes
and they can be locked as read-only later on via bpf_prog_select_runtime().

With a bit of rearranging, this also allows us to shrink bpf_prog_aux
to exactly 1 cacheline.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/linux/bpf.h    | 4 +---
 include/linux/filter.h | 4 +++-
 kernel/bpf/syscall.c   | 7 +++----
 kernel/bpf/verifier.c  | 4 ++--
 net/core/filter.c      | 4 ++--
 5 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 9c45814..a1a7ff2 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -117,11 +117,9 @@ struct bpf_prog;
 
 struct bpf_prog_aux {
 	atomic_t refcnt;
-	bool is_gpl_compatible;
-	enum bpf_prog_type prog_type;
+	u32 used_map_cnt;
 	const struct bpf_verifier_ops *ops;
 	struct bpf_map **used_maps;
-	u32 used_map_cnt;
 	struct bpf_prog *prog;
 	struct work_struct work;
 };
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 5e3863d..9ee8c67 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -308,9 +308,11 @@ struct bpf_binary_header {
 struct bpf_prog {
 	u16			pages;		/* Number of allocated pages */
 	bool			jited;		/* Is our filter JIT'ed? */
+	bool			gpl_compatible;	/* Is our filter GPL compatible? */
 	u32			len;		/* Number of filter blocks */
-	struct sock_fprog_kern	*orig_prog;	/* Original BPF program */
+	enum bpf_prog_type	type;		/* Type of BPF program */
 	struct bpf_prog_aux	*aux;		/* Auxiliary fields */
+	struct sock_fprog_kern	*orig_prog;	/* Original BPF program */
 	unsigned int		(*bpf_func)(const struct sk_buff *skb,
 					    const struct bpf_insn *filter);
 	/* Instructions for interpreter */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 536edc2..0d69449 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -354,10 +354,11 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
 	list_for_each_entry(tl, &bpf_prog_types, list_node) {
 		if (tl->type == type) {
 			prog->aux->ops = tl->ops;
-			prog->aux->prog_type = type;
+			prog->type = type;
 			return 0;
 		}
 	}
+
 	return -EINVAL;
 }
 
@@ -508,7 +509,7 @@ static int bpf_prog_load(union bpf_attr *attr)
 	prog->jited = false;
 
 	atomic_set(&prog->aux->refcnt, 1);
-	prog->aux->is_gpl_compatible = is_gpl;
+	prog->gpl_compatible = is_gpl;
 
 	/* find program type: socket_filter vs tracing_filter */
 	err = find_prog_type(type, prog);
@@ -517,7 +518,6 @@ static int bpf_prog_load(union bpf_attr *attr)
 
 	/* run eBPF verifier */
 	err = bpf_check(prog, attr);
-
 	if (err < 0)
 		goto free_used_maps;
 
@@ -528,7 +528,6 @@ static int bpf_prog_load(union bpf_attr *attr)
 	bpf_prog_select_runtime(prog);
 
 	err = anon_inode_getfd("bpf-prog", &bpf_prog_fops, prog, O_RDWR | O_CLOEXEC);
-
 	if (err < 0)
 		/* failed to allocate fd */
 		goto free_used_maps;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 594d341..bdf4192 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -852,7 +852,7 @@ static int check_call(struct verifier_env *env, int func_id)
 	}
 
 	/* eBPF programs must be GPL compatible to use GPL-ed functions */
-	if (!env->prog->aux->is_gpl_compatible && fn->gpl_only) {
+	if (!env->prog->gpl_compatible && fn->gpl_only) {
 		verbose("cannot call GPL only function from proprietary program\n");
 		return -EINVAL;
 	}
@@ -1205,7 +1205,7 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
 	struct reg_state *reg;
 	int i, err;
 
-	if (!may_access_skb(env->prog->aux->prog_type)) {
+	if (!may_access_skb(env->prog->type)) {
 		verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n");
 		return -EINVAL;
 	}
diff --git a/net/core/filter.c b/net/core/filter.c
index 514d408..ff000cb 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -814,7 +814,7 @@ static void bpf_release_orig_filter(struct bpf_prog *fp)
 
 static void __bpf_prog_release(struct bpf_prog *prog)
 {
-	if (prog->aux->prog_type == BPF_PROG_TYPE_SOCKET_FILTER) {
+	if (prog->type == BPF_PROG_TYPE_SOCKET_FILTER) {
 		bpf_prog_put(prog);
 	} else {
 		bpf_release_orig_filter(prog);
@@ -1105,7 +1105,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk)
 	if (IS_ERR(prog))
 		return PTR_ERR(prog);
 
-	if (prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) {
+	if (prog->type != BPF_PROG_TYPE_SOCKET_FILTER) {
 		bpf_prog_put(prog);
 		return -EINVAL;
 	}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 08/10] x86: unexport set_memory_ro and set_memory_rw
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (6 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 07/10] ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-28 10:00   ` [tip:x86/mm] x86/mm: Unexport set_memory_ro() and set_memory_rw() tip-bot for Daniel Borkmann
  2015-02-27 14:55 ` [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw Daniel Borkmann
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem
  Cc: ast, netdev, Daniel Borkmann, Bruce Allan, Jesse Brandeburg,
	Ingo Molnar, linux-kernel

This effectively unexports set_memory_ro and set_memory_rw functions, and
thus reverts a03352d2c1dc ("x86: export set_memory_ro and set_memory_rw").

They have been introduced for debugging purposes in e1000e, but no module
user is in mainline kernel (anymore?) and we explicitly do not want modules
to use these functions, as they i.e. protect eBPF (interpreted & JIT'ed)
images from malicious modifications or bugs.

Outside of eBPF scope, I believe also other set_memory_* functions should
be unexported on x86 for modules.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Bruce Allan <bruce.w.allan@intel.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 arch/x86/mm/pageattr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 536ea2f..81e8282 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -1654,13 +1654,11 @@ int set_memory_ro(unsigned long addr, int numpages)
 {
 	return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_RW), 0);
 }
-EXPORT_SYMBOL_GPL(set_memory_ro);
 
 int set_memory_rw(unsigned long addr, int numpages)
 {
 	return change_page_attr_set(&addr, numpages, __pgprot(_PAGE_RW), 0);
 }
-EXPORT_SYMBOL_GPL(set_memory_rw);
 
 int set_memory_np(unsigned long addr, int numpages)
 {
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (7 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 08/10] x86: unexport set_memory_ro and set_memory_rw Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-02-27 18:51   ` Laura Abbott
  2015-02-27 19:54   ` Will Deacon
  2015-02-27 14:55 ` [PATCH net-next 10/10] cls_bpf: add initial eBPF support for programmable classifiers Daniel Borkmann
  2015-03-01  5:28 ` [PATCH net-next 00/10] eBPF support for cls_bpf David Miller
  10 siblings, 2 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem
  Cc: ast, netdev, Daniel Borkmann, Laura Abbott, Will Deacon, linux-kernel

This effectively unexports set_memory_ro and set_memory_rw functions from
commit 11d91a770f1f ("arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support").

No module user of those is in mainline kernel and we explicitly do not want
modules to use these functions, as they i.e. protect eBPF (interpreted and
JIT'ed) images from malicious modifications or bugs.

Outside of eBPF scope, I believe also other set_memory_* functions should
be unexported on arm64 for modules.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Laura Abbott <lauraa@codeaurora.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 arch/arm64/mm/pageattr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index bb0ea94..8659357 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -70,7 +70,6 @@ int set_memory_ro(unsigned long addr, int numpages)
 					__pgprot(PTE_RDONLY),
 					__pgprot(PTE_WRITE));
 }
-EXPORT_SYMBOL_GPL(set_memory_ro);
 
 int set_memory_rw(unsigned long addr, int numpages)
 {
@@ -78,7 +77,6 @@ int set_memory_rw(unsigned long addr, int numpages)
 					__pgprot(PTE_WRITE),
 					__pgprot(PTE_RDONLY));
 }
-EXPORT_SYMBOL_GPL(set_memory_rw);
 
 int set_memory_nx(unsigned long addr, int numpages)
 {
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH net-next 10/10] cls_bpf: add initial eBPF support for programmable classifiers
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (8 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw Daniel Borkmann
@ 2015-02-27 14:55 ` Daniel Borkmann
  2015-03-01  5:28 ` [PATCH net-next 00/10] eBPF support for cls_bpf David Miller
  10 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 14:55 UTC (permalink / raw)
  To: davem; +Cc: ast, netdev, Daniel Borkmann, Jamal Hadi Salim, Jiri Pirko

This work extends the "classic" BPF programmable tc classifier by
extending its scope also to native eBPF code!

This allows for user space to implement own custom, 'safe' C like
classifiers (or whatever other frontend language LLVM et al may
provide in future), that can then be compiled with the LLVM eBPF
backend to an eBPF elf file. The result of this can be loaded into
the kernel via iproute2's tc. In the kernel, they can be JITed on
major archs and thus run in native performance.

Simple, minimal toy example to demonstrate the workflow:

  #include <linux/ip.h>
  #include <linux/if_ether.h>
  #include <linux/bpf.h>

  #include "tc_bpf_api.h"

  __section("classify")
  int cls_main(struct sk_buff *skb)
  {
    return (0x800 << 16) | load_byte(skb, ETH_HLEN + __builtin_offsetof(struct iphdr, tos));
  }

  char __license[] __section("license") = "GPL";

The classifier can then be compiled into eBPF opcodes and loaded
via tc, for example:

  clang -O2 -emit-llvm -c cls.c -o - | llc -march=bpf -filetype=obj -o cls.o
  tc filter add dev em1 parent 1: bpf cls.o [...]

As it has been demonstrated, the scope can even reach up to a fully
fledged flow dissector (similarly as in samples/bpf/sockex2_kern.c).

For tc, maps are allowed to be used, but from kernel context only,
in other words, eBPF code can keep state across filter invocations.
In future, we perhaps may reattach from a different application to
those maps e.g., to read out collected statistics/state.

Similarly as in socket filters, we may extend functionality for eBPF
classifiers over time depending on the use cases. For that purpose,
cls_bpf programs are using BPF_PROG_TYPE_SCHED_CLS program type, so
we can allow additional functions/accessors (e.g. an ABI compatible
offset translation to skb fields/metadata). For an initial cls_bpf
support, we allow the same set of helper functions as eBPF socket
filters, but we could diverge at some point in time w/o problem.

I was wondering whether cls_bpf and act_bpf could share C programs,
I can imagine that at some point, we introduce i) further common
handlers for both (or even beyond their scope), and/or if truly needed
ii) some restricted function space for each of them. Both can be
abstracted easily through struct bpf_verifier_ops in future.

The context of cls_bpf versus act_bpf is slightly different though:
a cls_bpf program will return a specific classid whereas act_bpf a
drop/non-drop return code, latter may also in future mangle skbs.
That said, we can surely have a "classify" and "action" section in
a single object file, or considered mentioned constraint add a
possibility of a shared section.

The workflow for getting native eBPF running from tc [1] is as
follows: for f_bpf, I've added a slightly modified ELF parser code
from Alexei's kernel sample, which reads out the LLVM compiled
object, sets up maps (and dynamically fixes up map fds) if any, and
loads the eBPF instructions all centrally through the bpf syscall.

The resulting fd from the loaded program itself is being passed down
to cls_bpf, which looks up struct bpf_prog from the fd store, and
holds reference, so that it stays available also after tc program
lifetime. On tc filter destruction, it will then drop its reference.

Moreover, I've also added the optional possibility to annotate an
eBPF filter with a name (e.g. path to object file, or something
else if preferred) so that when tc dumps currently installed filters,
some more context can be given to an admin for a given instance (as
opposed to just the file descriptor number).

Last but not least, bpf_prog_get() and bpf_prog_put() needed to be
exported, so that eBPF can be used from cls_bpf built as a module.
Thanks to 60a3b2253c41 ("net: bpf: make eBPF interpreter images
read-only") I think this is of no concern since anything wanting to
alter eBPF opcode after verification stage would crash the kernel.

  [1] http://git.breakpoint.cc/cgit/dborkman/iproute2.git/log/?h=ebpf

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
---
 include/uapi/linux/pkt_cls.h |   2 +
 kernel/bpf/syscall.c         |   2 +
 net/sched/cls_bpf.c          | 206 ++++++++++++++++++++++++++++++++-----------
 3 files changed, 158 insertions(+), 52 deletions(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 25731df..bf08e76 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -397,6 +397,8 @@ enum {
 	TCA_BPF_CLASSID,
 	TCA_BPF_OPS_LEN,
 	TCA_BPF_OPS,
+	TCA_BPF_FD,
+	TCA_BPF_NAME,
 	__TCA_BPF_MAX,
 };
 
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0d69449..669719c 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -419,6 +419,7 @@ void bpf_prog_put(struct bpf_prog *prog)
 		bpf_prog_free(prog);
 	}
 }
+EXPORT_SYMBOL_GPL(bpf_prog_put);
 
 static int bpf_prog_release(struct inode *inode, struct file *filp)
 {
@@ -466,6 +467,7 @@ struct bpf_prog *bpf_prog_get(u32 ufd)
 	fdput(f);
 	return prog;
 }
+EXPORT_SYMBOL_GPL(bpf_prog_get);
 
 /* last field in 'union bpf_attr' used by this command */
 #define	BPF_PROG_LOAD_LAST_FIELD log_buf
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 5f3ee9e..6f7ed8f 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/skbuff.h>
 #include <linux/filter.h>
+#include <linux/bpf.h>
+
 #include <net/rtnetlink.h>
 #include <net/pkt_cls.h>
 #include <net/sock.h>
@@ -24,6 +26,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>");
 MODULE_DESCRIPTION("TC BPF based classifier");
 
+#define CLS_BPF_NAME_LEN	256
+
 struct cls_bpf_head {
 	struct list_head plist;
 	u32 hgen;
@@ -32,18 +36,24 @@ struct cls_bpf_head {
 
 struct cls_bpf_prog {
 	struct bpf_prog *filter;
-	struct sock_filter *bpf_ops;
-	struct tcf_exts exts;
-	struct tcf_result res;
 	struct list_head link;
+	struct tcf_result res;
+	struct tcf_exts exts;
 	u32 handle;
-	u16 bpf_num_ops;
+	union {
+		u32 bpf_fd;
+		u16 bpf_num_ops;
+	};
+	struct sock_filter *bpf_ops;
+	const char *bpf_name;
 	struct tcf_proto *tp;
 	struct rcu_head rcu;
 };
 
 static const struct nla_policy bpf_policy[TCA_BPF_MAX + 1] = {
 	[TCA_BPF_CLASSID]	= { .type = NLA_U32 },
+	[TCA_BPF_FD]		= { .type = NLA_U32 },
+	[TCA_BPF_NAME]		= { .type = NLA_NUL_STRING, .len = CLS_BPF_NAME_LEN },
 	[TCA_BPF_OPS_LEN]	= { .type = NLA_U16 },
 	[TCA_BPF_OPS]		= { .type = NLA_BINARY,
 				    .len = sizeof(struct sock_filter) * BPF_MAXINSNS },
@@ -76,6 +86,11 @@ static int cls_bpf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 	return -1;
 }
 
+static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog)
+{
+	return !prog->bpf_ops;
+}
+
 static int cls_bpf_init(struct tcf_proto *tp)
 {
 	struct cls_bpf_head *head;
@@ -94,8 +109,12 @@ static void cls_bpf_delete_prog(struct tcf_proto *tp, struct cls_bpf_prog *prog)
 {
 	tcf_exts_destroy(&prog->exts);
 
-	bpf_prog_destroy(prog->filter);
+	if (cls_bpf_is_ebpf(prog))
+		bpf_prog_put(prog->filter);
+	else
+		bpf_prog_destroy(prog->filter);
 
+	kfree(prog->bpf_name);
 	kfree(prog->bpf_ops);
 	kfree(prog);
 }
@@ -114,6 +133,7 @@ static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg)
 	list_del_rcu(&prog->link);
 	tcf_unbind_filter(tp, &prog->res);
 	call_rcu(&prog->rcu, __cls_bpf_delete_prog);
+
 	return 0;
 }
 
@@ -151,69 +171,121 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle)
 	return ret;
 }
 
-static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
-				   struct cls_bpf_prog *prog,
-				   unsigned long base, struct nlattr **tb,
-				   struct nlattr *est, bool ovr)
+static int cls_bpf_prog_from_ops(struct nlattr **tb,
+				 struct cls_bpf_prog *prog, u32 classid)
 {
 	struct sock_filter *bpf_ops;
-	struct tcf_exts exts;
-	struct sock_fprog_kern tmp;
+	struct sock_fprog_kern fprog_tmp;
 	struct bpf_prog *fp;
 	u16 bpf_size, bpf_num_ops;
-	u32 classid;
 	int ret;
 
-	if (!tb[TCA_BPF_OPS_LEN] || !tb[TCA_BPF_OPS] || !tb[TCA_BPF_CLASSID])
-		return -EINVAL;
-
-	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
-	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
-	if (ret < 0)
-		return ret;
-
-	classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
 	bpf_num_ops = nla_get_u16(tb[TCA_BPF_OPS_LEN]);
-	if (bpf_num_ops > BPF_MAXINSNS || bpf_num_ops == 0) {
-		ret = -EINVAL;
-		goto errout;
-	}
+	if (bpf_num_ops > BPF_MAXINSNS || bpf_num_ops == 0)
+		return -EINVAL;
 
 	bpf_size = bpf_num_ops * sizeof(*bpf_ops);
-	if (bpf_size != nla_len(tb[TCA_BPF_OPS])) {
-		ret = -EINVAL;
-		goto errout;
-	}
+	if (bpf_size != nla_len(tb[TCA_BPF_OPS]))
+		return -EINVAL;
 
 	bpf_ops = kzalloc(bpf_size, GFP_KERNEL);
-	if (bpf_ops == NULL) {
-		ret = -ENOMEM;
-		goto errout;
-	}
+	if (bpf_ops == NULL)
+		return -ENOMEM;
 
 	memcpy(bpf_ops, nla_data(tb[TCA_BPF_OPS]), bpf_size);
 
-	tmp.len = bpf_num_ops;
-	tmp.filter = bpf_ops;
+	fprog_tmp.len = bpf_num_ops;
+	fprog_tmp.filter = bpf_ops;
 
-	ret = bpf_prog_create(&fp, &tmp);
-	if (ret)
-		goto errout_free;
+	ret = bpf_prog_create(&fp, &fprog_tmp);
+	if (ret < 0) {
+		kfree(bpf_ops);
+		return ret;
+	}
 
-	prog->bpf_num_ops = bpf_num_ops;
 	prog->bpf_ops = bpf_ops;
+	prog->bpf_num_ops = bpf_num_ops;
+	prog->bpf_name = NULL;
+
 	prog->filter = fp;
 	prog->res.classid = classid;
 
+	return 0;
+}
+
+static int cls_bpf_prog_from_efd(struct nlattr **tb,
+				 struct cls_bpf_prog *prog, u32 classid)
+{
+	struct bpf_prog *fp;
+	char *name = NULL;
+	u32 bpf_fd;
+
+	bpf_fd = nla_get_u32(tb[TCA_BPF_FD]);
+
+	fp = bpf_prog_get(bpf_fd);
+	if (IS_ERR(fp))
+		return PTR_ERR(fp);
+
+	if (fp->type != BPF_PROG_TYPE_SCHED_CLS) {
+		bpf_prog_put(fp);
+		return -EINVAL;
+	}
+
+	if (tb[TCA_BPF_NAME]) {
+		name = kmemdup(nla_data(tb[TCA_BPF_NAME]),
+			       nla_len(tb[TCA_BPF_NAME]),
+			       GFP_KERNEL);
+		if (!name) {
+			bpf_prog_put(fp);
+			return -ENOMEM;
+		}
+	}
+
+	prog->bpf_ops = NULL;
+	prog->bpf_fd = bpf_fd;
+	prog->bpf_name = name;
+
+	prog->filter = fp;
+	prog->res.classid = classid;
+
+	return 0;
+}
+
+static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
+				   struct cls_bpf_prog *prog,
+				   unsigned long base, struct nlattr **tb,
+				   struct nlattr *est, bool ovr)
+{
+	struct tcf_exts exts;
+	bool is_bpf, is_ebpf;
+	u32 classid;
+	int ret;
+
+	is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS];
+	is_ebpf = tb[TCA_BPF_FD];
+
+	if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf) ||
+	    !tb[TCA_BPF_CLASSID])
+		return -EINVAL;
+
+	tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
+	ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
+	if (ret < 0)
+		return ret;
+
+	classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
+
+	ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog, classid) :
+		       cls_bpf_prog_from_efd(tb, prog, classid);
+	if (ret < 0) {
+		tcf_exts_destroy(&exts);
+		return ret;
+	}
+
 	tcf_bind_filter(tp, &prog->res, base);
 	tcf_exts_change(tp, &prog->exts, &exts);
 
 	return 0;
-errout_free:
-	kfree(bpf_ops);
-errout:
-	tcf_exts_destroy(&exts);
-	return ret;
 }
 
 static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp,
@@ -297,11 +369,43 @@ errout:
 	return ret;
 }
 
+static int cls_bpf_dump_bpf_info(const struct cls_bpf_prog *prog,
+				 struct sk_buff *skb)
+{
+	struct nlattr *nla;
+
+	if (nla_put_u16(skb, TCA_BPF_OPS_LEN, prog->bpf_num_ops))
+		return -EMSGSIZE;
+
+	nla = nla_reserve(skb, TCA_BPF_OPS, prog->bpf_num_ops *
+			  sizeof(struct sock_filter));
+	if (nla == NULL)
+		return -EMSGSIZE;
+
+	memcpy(nla_data(nla), prog->bpf_ops, nla_len(nla));
+
+	return 0;
+}
+
+static int cls_bpf_dump_ebpf_info(const struct cls_bpf_prog *prog,
+				  struct sk_buff *skb)
+{
+	if (nla_put_u32(skb, TCA_BPF_FD, prog->bpf_fd))
+		return -EMSGSIZE;
+
+	if (prog->bpf_name &&
+	    nla_put_string(skb, TCA_BPF_NAME, prog->bpf_name))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
 static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 			struct sk_buff *skb, struct tcmsg *tm)
 {
 	struct cls_bpf_prog *prog = (struct cls_bpf_prog *) fh;
-	struct nlattr *nest, *nla;
+	struct nlattr *nest;
+	int ret;
 
 	if (prog == NULL)
 		return skb->len;
@@ -314,16 +418,14 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 
 	if (nla_put_u32(skb, TCA_BPF_CLASSID, prog->res.classid))
 		goto nla_put_failure;
-	if (nla_put_u16(skb, TCA_BPF_OPS_LEN, prog->bpf_num_ops))
-		goto nla_put_failure;
 
-	nla = nla_reserve(skb, TCA_BPF_OPS, prog->bpf_num_ops *
-			  sizeof(struct sock_filter));
-	if (nla == NULL)
+	if (cls_bpf_is_ebpf(prog))
+		ret = cls_bpf_dump_ebpf_info(prog, skb);
+	else
+		ret = cls_bpf_dump_bpf_info(prog, skb);
+	if (ret)
 		goto nla_put_failure;
 
-	memcpy(nla_data(nla), prog->bpf_ops, nla_len(nla));
-
 	if (tcf_exts_dump(skb, &prog->exts) < 0)
 		goto nla_put_failure;
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw
  2015-02-27 14:55 ` [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw Daniel Borkmann
@ 2015-02-27 18:51   ` Laura Abbott
  2015-02-27 19:54   ` Will Deacon
  1 sibling, 0 replies; 19+ messages in thread
From: Laura Abbott @ 2015-02-27 18:51 UTC (permalink / raw)
  To: Daniel Borkmann, davem; +Cc: ast, netdev, Will Deacon, linux-kernel

On 2/27/2015 6:55 AM, Daniel Borkmann wrote:
> This effectively unexports set_memory_ro and set_memory_rw functions from
> commit 11d91a770f1f ("arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support").
>
> No module user of those is in mainline kernel and we explicitly do not want
> modules to use these functions, as they i.e. protect eBPF (interpreted and
> JIT'ed) images from malicious modifications or bugs.
>
> Outside of eBPF scope, I believe also other set_memory_* functions should
> be unexported on arm64 for modules.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Alexei Starovoitov <ast@plumgrid.com>
> ---
>   arch/arm64/mm/pageattr.c | 2 --
>   1 file changed, 2 deletions(-)
>

We have some uses for modules doing set_memory_ro/rw but none that are
in mainline. That can be dealt with if the features ever get
mainlined which seems unlikely.

Acked-by: Laura Abbott <lauraa@codeaurora.org>

> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index bb0ea94..8659357 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -70,7 +70,6 @@ int set_memory_ro(unsigned long addr, int numpages)
>   					__pgprot(PTE_RDONLY),
>   					__pgprot(PTE_WRITE));
>   }
> -EXPORT_SYMBOL_GPL(set_memory_ro);
>
>   int set_memory_rw(unsigned long addr, int numpages)
>   {
> @@ -78,7 +77,6 @@ int set_memory_rw(unsigned long addr, int numpages)
>   					__pgprot(PTE_WRITE),
>   					__pgprot(PTE_RDONLY));
>   }
> -EXPORT_SYMBOL_GPL(set_memory_rw);
>
>   int set_memory_nx(unsigned long addr, int numpages)
>   {
>


-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw
  2015-02-27 14:55 ` [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw Daniel Borkmann
  2015-02-27 18:51   ` Laura Abbott
@ 2015-02-27 19:54   ` Will Deacon
  2015-02-27 20:05     ` Daniel Borkmann
  1 sibling, 1 reply; 19+ messages in thread
From: Will Deacon @ 2015-02-27 19:54 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, ast, netdev, Laura Abbott, linux-kernel

On Fri, Feb 27, 2015 at 02:55:41PM +0000, Daniel Borkmann wrote:
> This effectively unexports set_memory_ro and set_memory_rw functions from
> commit 11d91a770f1f ("arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support").
> 
> No module user of those is in mainline kernel and we explicitly do not want
> modules to use these functions, as they i.e. protect eBPF (interpreted and
> JIT'ed) images from malicious modifications or bugs.
> 
> Outside of eBPF scope, I believe also other set_memory_* functions should
> be unexported on arm64 for modules.
> 
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Laura Abbott <lauraa@codeaurora.org>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Alexei Starovoitov <ast@plumgrid.com>
> ---
>  arch/arm64/mm/pageattr.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
> index bb0ea94..8659357 100644
> --- a/arch/arm64/mm/pageattr.c
> +++ b/arch/arm64/mm/pageattr.c
> @@ -70,7 +70,6 @@ int set_memory_ro(unsigned long addr, int numpages)
>  					__pgprot(PTE_RDONLY),
>  					__pgprot(PTE_WRITE));
>  }
> -EXPORT_SYMBOL_GPL(set_memory_ro);
>  
>  int set_memory_rw(unsigned long addr, int numpages)
>  {
> @@ -78,7 +77,6 @@ int set_memory_rw(unsigned long addr, int numpages)
>  					__pgprot(PTE_WRITE),
>  					__pgprot(PTE_RDONLY));
>  }
> -EXPORT_SYMBOL_GPL(set_memory_rw);
>  
>  int set_memory_nx(unsigned long addr, int numpages)
>  {

Looks good to me. Can this be applied independently, or does it need to
remain part of your series?

Will

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw
  2015-02-27 19:54   ` Will Deacon
@ 2015-02-27 20:05     ` Daniel Borkmann
  2015-03-01  9:52       ` Daniel Borkmann
  0 siblings, 1 reply; 19+ messages in thread
From: Daniel Borkmann @ 2015-02-27 20:05 UTC (permalink / raw)
  To: Will Deacon; +Cc: davem, ast, netdev, Laura Abbott, linux-kernel

On 02/27/2015 08:54 PM, Will Deacon wrote:
...
> Looks good to me. Can this be applied independently, or does it need to
> remain part of your series?

Ideally, it should be seen as part of this series, but I have no problem
if this one goes via arm64 tree, instead. What Dave and you prefer. ;)

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [tip:x86/mm] x86/mm: Unexport set_memory_ro() and set_memory_rw()
  2015-02-27 14:55 ` [PATCH net-next 08/10] x86: unexport set_memory_ro and set_memory_rw Daniel Borkmann
@ 2015-02-28 10:00   ` tip-bot for Daniel Borkmann
  2015-02-28 12:53     ` Arjan van de Ven
  0 siblings, 1 reply; 19+ messages in thread
From: tip-bot for Daniel Borkmann @ 2015-02-28 10:00 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jesse.brandeburg, mingo, linux-kernel, arjan, daniel, ast,
	bruce.w.allan, hpa, tglx, bp

Commit-ID:  6bbb614ec478961c7443086bdf7fd6784479c14a
Gitweb:     http://git.kernel.org/tip/6bbb614ec478961c7443086bdf7fd6784479c14a
Author:     Daniel Borkmann <daniel@iogearbox.net>
AuthorDate: Fri, 27 Feb 2015 15:55:40 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sat, 28 Feb 2015 10:41:59 +0100

x86/mm: Unexport set_memory_ro() and set_memory_rw()

This effectively unexports set_memory_ro() and set_memory_rw()
functions, and thus reverts:

  a03352d2c1dc ("x86: export set_memory_ro and set_memory_rw").

They have been introduced for debugging purposes in e1000e, but
no module user is in mainline kernel (anymore?) and we
explicitly do not want modules to use these functions, as they
i.e. protect eBPF (interpreted & JIT'ed) images from malicious
modifications or bugs.

Outside of eBPF scope, I believe also other set_memory_*()
functions should be unexported on x86 for modules.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Bruce Allan <bruce.w.allan@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: davem@davemloft.net
Link: http://lkml.kernel.org/r/a064393a0a5d319eebde5c761cfd743132d4f213.1425040940.git.daniel@iogearbox.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/mm/pageattr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 536ea2f..81e8282 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -1654,13 +1654,11 @@ int set_memory_ro(unsigned long addr, int numpages)
 {
 	return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_RW), 0);
 }
-EXPORT_SYMBOL_GPL(set_memory_ro);
 
 int set_memory_rw(unsigned long addr, int numpages)
 {
 	return change_page_attr_set(&addr, numpages, __pgprot(_PAGE_RW), 0);
 }
-EXPORT_SYMBOL_GPL(set_memory_rw);
 
 int set_memory_np(unsigned long addr, int numpages)
 {

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [tip:x86/mm] x86/mm: Unexport set_memory_ro() and set_memory_rw()
  2015-02-28 10:00   ` [tip:x86/mm] x86/mm: Unexport set_memory_ro() and set_memory_rw() tip-bot for Daniel Borkmann
@ 2015-02-28 12:53     ` Arjan van de Ven
  0 siblings, 0 replies; 19+ messages in thread
From: Arjan van de Ven @ 2015-02-28 12:53 UTC (permalink / raw)
  To: jesse.brandeburg, mingo, linux-kernel, ast, daniel,
	bruce.w.allan, hpa, tglx, bp, linux-tip-commits

On 2/28/2015 2:00 AM, tip-bot for Daniel Borkmann wrote:
> Commit-ID:  6bbb614ec478961c7443086bdf7fd6784479c14a
> Gitweb:     http://git.kernel.org/tip/6bbb614ec478961c7443086bdf7fd6784479c14a
> Author:     Daniel Borkmann <daniel@iogearbox.net>
> AuthorDate: Fri, 27 Feb 2015 15:55:40 +0100
> Committer:  Ingo Molnar <mingo@kernel.org>
> CommitDate: Sat, 28 Feb 2015 10:41:59 +0100
>
> x86/mm: Unexport set_memory_ro() and set_memory_rw()
>
> This effectively unexports set_memory_ro() and set_memory_rw()
> functions, and thus reverts:
>
>    a03352d2c1dc ("x86: export set_memory_ro and set_memory_rw").
>
> They have been introduced for debugging purposes in e1000e, but
> no module user is in mainline kernel (anymore?) and we
> explicitly do not want modules to use these functions, as they
> i.e. protect eBPF (interpreted & JIT'ed) images from malicious
> modifications or bugs.
>
> Outside of eBPF scope, I believe also other set_memory_*()
> functions should be unexported on x86 for modules.
>

Acked-by: Arjan van de Ven <arjan@linux.intel.com>



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 00/10] eBPF support for cls_bpf
  2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
                   ` (9 preceding siblings ...)
  2015-02-27 14:55 ` [PATCH net-next 10/10] cls_bpf: add initial eBPF support for programmable classifiers Daniel Borkmann
@ 2015-03-01  5:28 ` David Miller
  2015-03-01  9:49   ` Daniel Borkmann
  10 siblings, 1 reply; 19+ messages in thread
From: David Miller @ 2015-03-01  5:28 UTC (permalink / raw)
  To: daniel; +Cc: ast, netdev

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 27 Feb 2015 15:55:32 +0100

> This is the non-RFC version of my patchset posted before netdev01 [1]
> conference. It contains a couple of eBPF cleanups and preparation
> patches to get eBPF support into cls_bpf. The last patch adds the
> actual support. I'll post the iproute2 parts after the kernel bits
> are merged, an initial preview link to the code is mentioned in the
> last patch.
> 
> Patch 4 and 5 were originally one patch, but I've split them into
> two parts upon request as patch 4 only is also needed for Alexei's
> tracing patches that go via tip tree.
> 
> Tested with tc and all in-kernel available test suites.
> 
> I have configured and built LLVM with --enable-experimental-targets=BPF
> but as Alexei put it, the plan is to get rid of the experimental
> status in future [2].

Daniel please respin this without the arch patches, those should
go via the various arch maintainer's tree(s).

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 00/10] eBPF support for cls_bpf
  2015-03-01  5:28 ` [PATCH net-next 00/10] eBPF support for cls_bpf David Miller
@ 2015-03-01  9:49   ` Daniel Borkmann
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-03-01  9:49 UTC (permalink / raw)
  To: David Miller; +Cc: ast, netdev

On 03/01/2015 06:28 AM, David Miller wrote:
...
> Daniel please respin this without the arch patches, those should
> go via the various arch maintainer's tree(s).

Okay, will do.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw
  2015-02-27 20:05     ` Daniel Borkmann
@ 2015-03-01  9:52       ` Daniel Borkmann
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Borkmann @ 2015-03-01  9:52 UTC (permalink / raw)
  To: Will Deacon; +Cc: davem, ast, netdev, Laura Abbott, linux-kernel

Hi Will,

On 02/27/2015 09:05 PM, Daniel Borkmann wrote:
> On 02/27/2015 08:54 PM, Will Deacon wrote:
> ...
>> Looks good to me. Can this be applied independently, or does it need to
>> remain part of your series?
>
> Ideally, it should be seen as part of this series, but I have no problem
> if this one goes via arm64 tree, instead. What Dave and you prefer. ;)

I'll resend you this one directly as a stand-alone patch to arm64,
with Acked-by's preserved.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2015-03-01  9:52 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-27 14:55 [PATCH net-next 00/10] eBPF support for cls_bpf Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 01/10] ebpf: remove kernel test stubs Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 02/10] ebpf: constify various function pointer structs Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 03/10] ebpf: export BPF_PSEUDO_MAP_FD to uapi Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 04/10] ebpf: make internal bpf API independent of CONFIG_BPF_SYSCALL ifdefs Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 05/10] ebpf: remove CONFIG_BPF_SYSCALL ifdefs in socket filter code Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 06/10] ebpf: add sched_cls_type and map it to sk_filter's verifier ops Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 07/10] ebpf: move read-only fields to bpf_prog and shrink bpf_prog_aux Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 08/10] x86: unexport set_memory_ro and set_memory_rw Daniel Borkmann
2015-02-28 10:00   ` [tip:x86/mm] x86/mm: Unexport set_memory_ro() and set_memory_rw() tip-bot for Daniel Borkmann
2015-02-28 12:53     ` Arjan van de Ven
2015-02-27 14:55 ` [PATCH net-next 09/10] arm64: unexport set_memory_ro and set_memory_rw Daniel Borkmann
2015-02-27 18:51   ` Laura Abbott
2015-02-27 19:54   ` Will Deacon
2015-02-27 20:05     ` Daniel Borkmann
2015-03-01  9:52       ` Daniel Borkmann
2015-02-27 14:55 ` [PATCH net-next 10/10] cls_bpf: add initial eBPF support for programmable classifiers Daniel Borkmann
2015-03-01  5:28 ` [PATCH net-next 00/10] eBPF support for cls_bpf David Miller
2015-03-01  9:49   ` Daniel Borkmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.