netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/4] BPF updates
@ 2015-05-06 14:12 Daniel Borkmann
  2015-05-06 14:12 ` [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations Daniel Borkmann
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Daniel Borkmann @ 2015-05-06 14:12 UTC (permalink / raw)
  To: davem; +Cc: ast, keescook, nschichan, netdev, Daniel Borkmann

This set gets rid of BPF special handling in seccomp filter preparation
and provides generic infrastructure from BPF side, which eventually also
allows for classic BPF JITs to add support for seccomp filters.

Daniel Borkmann (2):
  net: filter: add __GFP_NOWARN flag for larger kmem allocs
  seccomp, filter: add and use bpf_prog_create_from_user from seccomp

Nicolas Schichan (2):
  net: filter: add a callback to allow classic post-verifier transformations
  seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter

 include/linux/filter.h | 10 +++---
 kernel/seccomp.c       | 70 +++++++++---------------------------------
 net/core/filter.c      | 82 ++++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 91 insertions(+), 71 deletions(-)

-- 
1.9.3

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

* [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations
  2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
@ 2015-05-06 14:12 ` Daniel Borkmann
  2015-05-06 15:12   ` Alexei Starovoitov
  2015-05-06 14:12 ` [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter Daniel Borkmann
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2015-05-06 14:12 UTC (permalink / raw)
  To: davem; +Cc: ast, keescook, nschichan, netdev, Daniel Borkmann

From: Nicolas Schichan <nschichan@freebox.fr>

This is in preparation for use by the seccomp code, the rationale is
not to duplicate additional code within the seccomp layer, but instead,
have it abstracted and hidden within the classic BPF API.

As an interim step, this now also makes bpf_prepare_filter() visible
(not as exported symbol though), so that seccomp can reuse that code
path instead of reimplementing it.

Joint work with Daniel Borkmann.

Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
---
 include/linux/filter.h |  6 ++++++
 net/core/filter.c      | 18 +++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index fa11b3a..9199624 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -384,7 +384,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 int sk_attach_bpf(u32 ufd, struct sock *sk);
 int sk_detach_filter(struct sock *sk);
 
+typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
+				       unsigned int flen);
+
 int bpf_check_classic(const struct sock_filter *filter, unsigned int flen);
+struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
+				    bpf_aux_classic_check_t trans);
+
 int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
 		  unsigned int len);
 
diff --git a/net/core/filter.c b/net/core/filter.c
index bf831a8..e670494 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -988,7 +988,8 @@ out_err:
 	return ERR_PTR(err);
 }
 
-static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
+struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
+				    bpf_aux_classic_check_t trans)
 {
 	int err;
 
@@ -1001,6 +1002,17 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
 		return ERR_PTR(err);
 	}
 
+	/* There might be additional checks and transformations
+	 * needed on classic filters, f.e. in case of seccomp.
+	 */
+	if (trans) {
+		err = trans(fp->insns, fp->len);
+		if (err) {
+			__bpf_prog_release(fp);
+			return ERR_PTR(err);
+		}
+	}
+
 	/* Probe if we can JIT compile the filter and if so, do
 	 * the compilation of the filter.
 	 */
@@ -1050,7 +1062,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
 	/* bpf_prepare_filter() already takes care of freeing
 	 * memory in case something goes wrong.
 	 */
-	fp = bpf_prepare_filter(fp);
+	fp = bpf_prepare_filter(fp, NULL);
 	if (IS_ERR(fp))
 		return PTR_ERR(fp);
 
@@ -1135,7 +1147,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
 	/* bpf_prepare_filter() already takes care of freeing
 	 * memory in case something goes wrong.
 	 */
-	prog = bpf_prepare_filter(prog);
+	prog = bpf_prepare_filter(prog, NULL);
 	if (IS_ERR(prog))
 		return PTR_ERR(prog);
 
-- 
1.9.3

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

* [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter
  2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
  2015-05-06 14:12 ` [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations Daniel Borkmann
@ 2015-05-06 14:12 ` Daniel Borkmann
  2015-05-06 15:15   ` Alexei Starovoitov
  2015-05-06 14:12 ` [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs Daniel Borkmann
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2015-05-06 14:12 UTC (permalink / raw)
  To: davem; +Cc: ast, keescook, nschichan, netdev, Daniel Borkmann

From: Nicolas Schichan <nschichan@freebox.fr>

Remove the calls to bpf_check_classic(), bpf_convert_filter() and
bpf_migrate_runtime() and let bpf_prepare_filter() take care of that
instead.

seccomp_check_filter() is passed to bpf_prepare_filter() so that it
gets called from there, after bpf_check_classic().

We can now remove exposure of two internal classic BPF functions
previously used by seccomp. The export of bpf_check_classic() symbol,
previously known as sk_chk_filter(), was there since pre git times,
and no in-tree module was using it, therefore remove it.

Joint work with Daniel Borkmann.

Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
---
 include/linux/filter.h |  4 ---
 kernel/seccomp.c       | 68 ++++++++++++++++----------------------------------
 net/core/filter.c      |  8 +++---
 3 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 9199624..0dcb44b 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -363,9 +363,6 @@ int sk_filter(struct sock *sk, struct sk_buff *skb);
 void bpf_prog_select_runtime(struct bpf_prog *fp);
 void bpf_prog_free(struct bpf_prog *fp);
 
-int bpf_convert_filter(struct sock_filter *prog, int len,
-		       struct bpf_insn *new_prog, int *new_len);
-
 struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags);
 struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
 				  gfp_t gfp_extra_flags);
@@ -387,7 +384,6 @@ int sk_detach_filter(struct sock *sk);
 typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
 				       unsigned int flen);
 
-int bpf_check_classic(const struct sock_filter *filter, unsigned int flen);
 struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
 				    bpf_aux_classic_check_t trans);
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 4f44028..93d40f7 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -347,15 +347,14 @@ static inline void seccomp_sync_threads(void)
 static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 {
 	struct seccomp_filter *filter;
-	unsigned long fp_size;
-	struct sock_filter *fp;
-	int new_len;
-	long ret;
+	struct bpf_prog *prog;
+	unsigned long fsize;
 
 	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
 		return ERR_PTR(-EINVAL);
+
 	BUG_ON(INT_MAX / fprog->len < sizeof(struct sock_filter));
-	fp_size = fprog->len * sizeof(struct sock_filter);
+	fsize = bpf_classic_proglen(fprog);
 
 	/*
 	 * Installing a seccomp filter requires that the task has
@@ -368,60 +367,37 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 				     CAP_SYS_ADMIN) != 0)
 		return ERR_PTR(-EACCES);
 
-	fp = kzalloc(fp_size, GFP_KERNEL|__GFP_NOWARN);
-	if (!fp)
+	prog = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
+	if (!prog)
 		return ERR_PTR(-ENOMEM);
 
 	/* Copy the instructions from fprog. */
-	ret = -EFAULT;
-	if (copy_from_user(fp, fprog->filter, fp_size))
-		goto free_prog;
-
-	/* Check and rewrite the fprog via the skb checker */
-	ret = bpf_check_classic(fp, fprog->len);
-	if (ret)
-		goto free_prog;
+	if (copy_from_user(prog->insns, fprog->filter, fsize)) {
+		__bpf_prog_free(prog);
+		return ERR_PTR(-EFAULT);
+	}
 
-	/* Check and rewrite the fprog for seccomp use */
-	ret = seccomp_check_filter(fp, fprog->len);
-	if (ret)
-		goto free_prog;
+	prog->len = fprog->len;
 
-	/* Convert 'sock_filter' insns to 'bpf_insn' insns */
-	ret = bpf_convert_filter(fp, fprog->len, NULL, &new_len);
-	if (ret)
-		goto free_prog;
+	/* bpf_prepare_filter() already takes care of freeing
+	 * memory in case something goes wrong.
+	 */
+	prog = bpf_prepare_filter(prog, seccomp_check_filter);
+	if (IS_ERR(prog))
+		return ERR_CAST(prog);
 
 	/* Allocate a new seccomp_filter */
-	ret = -ENOMEM;
 	filter = kzalloc(sizeof(struct seccomp_filter),
 			 GFP_KERNEL|__GFP_NOWARN);
-	if (!filter)
-		goto free_prog;
-
-	filter->prog = bpf_prog_alloc(bpf_prog_size(new_len), __GFP_NOWARN);
-	if (!filter->prog)
-		goto free_filter;
-
-	ret = bpf_convert_filter(fp, fprog->len, filter->prog->insnsi, &new_len);
-	if (ret)
-		goto free_filter_prog;
+	if (!filter) {
+		bpf_prog_destroy(prog);
+		return ERR_PTR(-ENOMEM);
+	}
 
-	kfree(fp);
+	filter->prog = prog;
 	atomic_set(&filter->usage, 1);
-	filter->prog->len = new_len;
-
-	bpf_prog_select_runtime(filter->prog);
 
 	return filter;
-
-free_filter_prog:
-	__bpf_prog_free(filter->prog);
-free_filter:
-	kfree(filter);
-free_prog:
-	kfree(fp);
-	return ERR_PTR(ret);
 }
 
 /**
diff --git a/net/core/filter.c b/net/core/filter.c
index e670494..f887084 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -355,8 +355,8 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
  * for socket filters: ctx == 'struct sk_buff *', for seccomp:
  * ctx == 'struct seccomp_data *'.
  */
-int bpf_convert_filter(struct sock_filter *prog, int len,
-		       struct bpf_insn *new_prog, int *new_len)
+static int bpf_convert_filter(struct sock_filter *prog, int len,
+			      struct bpf_insn *new_prog, int *new_len)
 {
 	int new_flen = 0, pass = 0, target, i;
 	struct bpf_insn *new_insn;
@@ -751,7 +751,8 @@ static bool chk_code_allowed(u16 code_to_probe)
  *
  * Returns 0 if the rule set is legal or -EINVAL if not.
  */
-int bpf_check_classic(const struct sock_filter *filter, unsigned int flen)
+static int bpf_check_classic(const struct sock_filter *filter,
+			     unsigned int flen)
 {
 	bool anc_found;
 	int pc;
@@ -825,7 +826,6 @@ int bpf_check_classic(const struct sock_filter *filter, unsigned int flen)
 
 	return -EINVAL;
 }
-EXPORT_SYMBOL(bpf_check_classic);
 
 static int bpf_prog_store_orig_filter(struct bpf_prog *fp,
 				      const struct sock_fprog *fprog)
-- 
1.9.3

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

* [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs
  2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
  2015-05-06 14:12 ` [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations Daniel Borkmann
  2015-05-06 14:12 ` [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter Daniel Borkmann
@ 2015-05-06 14:12 ` Daniel Borkmann
  2015-05-06 15:16   ` Alexei Starovoitov
  2015-05-06 14:12 ` [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp Daniel Borkmann
  2015-05-09 21:33 ` [PATCH net-next 0/4] BPF updates David Miller
  4 siblings, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2015-05-06 14:12 UTC (permalink / raw)
  To: davem; +Cc: ast, keescook, nschichan, netdev, Daniel Borkmann

When seccomp BPF was added, it was discussed to add __GFP_NOWARN
flag for their configuration path as f.e. up to 32K allocations are
more prone to fail under stress. As we're going to reuse BPF API,
add __GFP_NOWARN flags where larger kmalloc() and friends allocations
could fail.

It doesn't make much sense to pass around __GFP_NOWARN everywhere as
an extra argument only for seccomp while we just as well could run
into similar issues for socket filters, where it's not desired to
have a user application throw a WARN() due to allocation failure.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Nicolas Schichan <nschichan@freebox.fr>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
---
 net/core/filter.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index f887084..45c015d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -371,7 +371,8 @@ static int bpf_convert_filter(struct sock_filter *prog, int len,
 		return -EINVAL;
 
 	if (new_prog) {
-		addrs = kcalloc(len, sizeof(*addrs), GFP_KERNEL);
+		addrs = kcalloc(len, sizeof(*addrs),
+				GFP_KERNEL | __GFP_NOWARN);
 		if (!addrs)
 			return -ENOMEM;
 	}
@@ -839,7 +840,9 @@ static int bpf_prog_store_orig_filter(struct bpf_prog *fp,
 
 	fkprog = fp->orig_prog;
 	fkprog->len = fprog->len;
-	fkprog->filter = kmemdup(fp->insns, fsize, GFP_KERNEL);
+
+	fkprog->filter = kmemdup(fp->insns, fsize,
+				 GFP_KERNEL | __GFP_NOWARN);
 	if (!fkprog->filter) {
 		kfree(fp->orig_prog);
 		return -ENOMEM;
@@ -941,7 +944,7 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
 	 * pass. At this time, the user BPF is stored in fp->insns.
 	 */
 	old_prog = kmemdup(fp->insns, old_len * sizeof(struct sock_filter),
-			   GFP_KERNEL);
+			   GFP_KERNEL | __GFP_NOWARN);
 	if (!old_prog) {
 		err = -ENOMEM;
 		goto out_err;
-- 
1.9.3

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

* [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp
  2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
                   ` (2 preceding siblings ...)
  2015-05-06 14:12 ` [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs Daniel Borkmann
@ 2015-05-06 14:12 ` Daniel Borkmann
  2015-05-06 15:21   ` Alexei Starovoitov
  2015-05-09 21:33 ` [PATCH net-next 0/4] BPF updates David Miller
  4 siblings, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2015-05-06 14:12 UTC (permalink / raw)
  To: davem; +Cc: ast, keescook, nschichan, netdev, Daniel Borkmann

Seccomp has always been a special candidate when it comes to preparation
of its filters in seccomp_prepare_filter(). Due to the extra checks and
filter rewrite it partially duplicates code and has BPF internals exposed.

This patch adds a generic API inside the BPF code code that seccomp can use
and thus keep it's filter preparation code minimal and better maintainable.
The other side-effect is that now classic JITs can add seccomp support as
well by only providing a BPF_LDX | BPF_W | BPF_ABS translation.

Tested with seccomp and BPF test suites.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Nicolas Schichan <nschichan@freebox.fr>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
---
 include/linux/filter.h | 12 +++++-------
 kernel/seccomp.c       | 42 ++++++++++++-----------------------------
 net/core/filter.c      | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 66 insertions(+), 39 deletions(-)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 0dcb44b..3c03a60 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -374,19 +374,17 @@ static inline void bpf_prog_unlock_free(struct bpf_prog *fp)
 	__bpf_prog_free(fp);
 }
 
+typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
+				       unsigned int flen);
+
 int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog);
+int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
+			      bpf_aux_classic_check_t trans);
 void bpf_prog_destroy(struct bpf_prog *fp);
 
 int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 int sk_attach_bpf(u32 ufd, struct sock *sk);
 int sk_detach_filter(struct sock *sk);
-
-typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
-				       unsigned int flen);
-
-struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
-				    bpf_aux_classic_check_t trans);
-
 int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
 		  unsigned int len);
 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 93d40f7..245df6b 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -346,15 +346,13 @@ static inline void seccomp_sync_threads(void)
  */
 static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 {
-	struct seccomp_filter *filter;
-	struct bpf_prog *prog;
-	unsigned long fsize;
+	struct seccomp_filter *sfilter;
+	int ret;
 
 	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)
 		return ERR_PTR(-EINVAL);
 
 	BUG_ON(INT_MAX / fprog->len < sizeof(struct sock_filter));
-	fsize = bpf_classic_proglen(fprog);
 
 	/*
 	 * Installing a seccomp filter requires that the task has
@@ -367,37 +365,21 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
 				     CAP_SYS_ADMIN) != 0)
 		return ERR_PTR(-EACCES);
 
-	prog = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
-	if (!prog)
-		return ERR_PTR(-ENOMEM);
-
-	/* Copy the instructions from fprog. */
-	if (copy_from_user(prog->insns, fprog->filter, fsize)) {
-		__bpf_prog_free(prog);
-		return ERR_PTR(-EFAULT);
-	}
-
-	prog->len = fprog->len;
-
-	/* bpf_prepare_filter() already takes care of freeing
-	 * memory in case something goes wrong.
-	 */
-	prog = bpf_prepare_filter(prog, seccomp_check_filter);
-	if (IS_ERR(prog))
-		return ERR_CAST(prog);
-
 	/* Allocate a new seccomp_filter */
-	filter = kzalloc(sizeof(struct seccomp_filter),
-			 GFP_KERNEL|__GFP_NOWARN);
-	if (!filter) {
-		bpf_prog_destroy(prog);
+	sfilter = kzalloc(sizeof(*sfilter), GFP_KERNEL | __GFP_NOWARN);
+	if (!sfilter)
 		return ERR_PTR(-ENOMEM);
+
+	ret = bpf_prog_create_from_user(&sfilter->prog, fprog,
+					seccomp_check_filter);
+	if (ret < 0) {
+		kfree(sfilter);
+		return ERR_PTR(ret);
 	}
 
-	filter->prog = prog;
-	atomic_set(&filter->usage, 1);
+	atomic_set(&sfilter->usage, 1);
 
-	return filter;
+	return sfilter;
 }
 
 /**
diff --git a/net/core/filter.c b/net/core/filter.c
index 45c015d..a831f19 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -991,8 +991,8 @@ out_err:
 	return ERR_PTR(err);
 }
 
-struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
-				    bpf_aux_classic_check_t trans)
+static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
+					   bpf_aux_classic_check_t trans)
 {
 	int err;
 
@@ -1074,6 +1074,53 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
 }
 EXPORT_SYMBOL_GPL(bpf_prog_create);
 
+/**
+ *	bpf_prog_create_from_user - create an unattached filter from user buffer
+ *	@pfp: the unattached filter that is created
+ *	@fprog: the filter program
+ *	@trans: post-classic verifier transformation handler
+ *
+ * This function effectively does the same as bpf_prog_create(), only
+ * that it builds up its insns buffer from user space provided buffer.
+ * It also allows for passing a bpf_aux_classic_check_t handler.
+ */
+int bpf_prog_create_from_user(struct bpf_prog **pfp, struct sock_fprog *fprog,
+			      bpf_aux_classic_check_t trans)
+{
+	unsigned int fsize = bpf_classic_proglen(fprog);
+	struct bpf_prog *fp;
+
+	/* Make sure new filter is there and in the right amounts. */
+	if (fprog->filter == NULL)
+		return -EINVAL;
+
+	fp = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
+	if (!fp)
+		return -ENOMEM;
+
+	if (copy_from_user(fp->insns, fprog->filter, fsize)) {
+		__bpf_prog_free(fp);
+		return -EFAULT;
+	}
+
+	fp->len = fprog->len;
+	/* Since unattached filters are not copied back to user
+	 * space through sk_get_filter(), we do not need to hold
+	 * a copy here, and can spare us the work.
+	 */
+	fp->orig_prog = NULL;
+
+	/* bpf_prepare_filter() already takes care of freeing
+	 * memory in case something goes wrong.
+	 */
+	fp = bpf_prepare_filter(fp, trans);
+	if (IS_ERR(fp))
+		return PTR_ERR(fp);
+
+	*pfp = fp;
+	return 0;
+}
+
 void bpf_prog_destroy(struct bpf_prog *fp)
 {
 	__bpf_prog_release(fp);
-- 
1.9.3

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

* Re: [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations
  2015-05-06 14:12 ` [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations Daniel Borkmann
@ 2015-05-06 15:12   ` Alexei Starovoitov
  0 siblings, 0 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2015-05-06 15:12 UTC (permalink / raw)
  To: Daniel Borkmann, davem; +Cc: keescook, nschichan, netdev

On 5/6/15 7:12 AM, Daniel Borkmann wrote:
> From: Nicolas Schichan <nschichan@freebox.fr>
>
> This is in preparation for use by the seccomp code, the rationale is
> not to duplicate additional code within the seccomp layer, but instead,
> have it abstracted and hidden within the classic BPF API.
>
> As an interim step, this now also makes bpf_prepare_filter() visible
> (not as exported symbol though), so that seccomp can reuse that code
> path instead of reimplementing it.
>
> Joint work with Daniel Borkmann.
>
> Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Alexei Starovoitov <ast@plumgrid.com>
> Cc: Kees Cook <keescook@chromium.org>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

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

* Re: [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter
  2015-05-06 14:12 ` [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter Daniel Borkmann
@ 2015-05-06 15:15   ` Alexei Starovoitov
  0 siblings, 0 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2015-05-06 15:15 UTC (permalink / raw)
  To: Daniel Borkmann, davem; +Cc: keescook, nschichan, netdev

On 5/6/15 7:12 AM, Daniel Borkmann wrote:
> From: Nicolas Schichan <nschichan@freebox.fr>
>
> Remove the calls to bpf_check_classic(), bpf_convert_filter() and
> bpf_migrate_runtime() and let bpf_prepare_filter() take care of that
> instead.
>
> seccomp_check_filter() is passed to bpf_prepare_filter() so that it
> gets called from there, after bpf_check_classic().
>
> We can now remove exposure of two internal classic BPF functions
> previously used by seccomp. The export of bpf_check_classic() symbol,
> previously known as sk_chk_filter(), was there since pre git times,
> and no in-tree module was using it, therefore remove it.
>
> Joint work with Daniel Borkmann.
>
> Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Alexei Starovoitov <ast@plumgrid.com>
> Cc: Kees Cook <keescook@chromium.org>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

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

* Re: [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs
  2015-05-06 14:12 ` [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs Daniel Borkmann
@ 2015-05-06 15:16   ` Alexei Starovoitov
  0 siblings, 0 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2015-05-06 15:16 UTC (permalink / raw)
  To: Daniel Borkmann, davem; +Cc: keescook, nschichan, netdev

On 5/6/15 7:12 AM, Daniel Borkmann wrote:
> When seccomp BPF was added, it was discussed to add __GFP_NOWARN
> flag for their configuration path as f.e. up to 32K allocations are
> more prone to fail under stress. As we're going to reuse BPF API,
> add __GFP_NOWARN flags where larger kmalloc() and friends allocations
> could fail.
>
> It doesn't make much sense to pass around __GFP_NOWARN everywhere as
> an extra argument only for seccomp while we just as well could run
> into similar issues for socket filters, where it's not desired to
> have a user application throw a WARN() due to allocation failure.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Nicolas Schichan <nschichan@freebox.fr>
> Cc: Alexei Starovoitov <ast@plumgrid.com>
> Cc: Kees Cook <keescook@chromium.org>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

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

* Re: [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp
  2015-05-06 14:12 ` [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp Daniel Borkmann
@ 2015-05-06 15:21   ` Alexei Starovoitov
  0 siblings, 0 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2015-05-06 15:21 UTC (permalink / raw)
  To: Daniel Borkmann, davem; +Cc: keescook, nschichan, netdev

On 5/6/15 7:12 AM, Daniel Borkmann wrote:
> Seccomp has always been a special candidate when it comes to preparation
> of its filters in seccomp_prepare_filter(). Due to the extra checks and
> filter rewrite it partially duplicates code and has BPF internals exposed.
>
> This patch adds a generic API inside the BPF code code that seccomp can use
> and thus keep it's filter preparation code minimal and better maintainable.
> The other side-effect is that now classic JITs can add seccomp support as
> well by only providing a BPF_LDX | BPF_W | BPF_ABS translation.
>
> Tested with seccomp and BPF test suites.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Nicolas Schichan <nschichan@freebox.fr>
> Cc: Alexei Starovoitov <ast@plumgrid.com>
> Cc: Kees Cook <keescook@chromium.org>

Acked-by: Alexei Starovoitov <ast@plumgrid.com>

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

* Re: [PATCH net-next 0/4] BPF updates
  2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
                   ` (3 preceding siblings ...)
  2015-05-06 14:12 ` [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp Daniel Borkmann
@ 2015-05-09 21:33 ` David Miller
  4 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2015-05-09 21:33 UTC (permalink / raw)
  To: daniel; +Cc: ast, keescook, nschichan, netdev

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Wed,  6 May 2015 16:12:26 +0200

> This set gets rid of BPF special handling in seccomp filter preparation
> and provides generic infrastructure from BPF side, which eventually also
> allows for classic BPF JITs to add support for seccomp filters.

I'll apply this series, thanks.

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

* Re: [PATCH net-next 0/4] BPF updates
  2015-10-16  1:09 Daniel Borkmann
@ 2015-10-19  2:53 ` David Miller
  0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2015-10-19  2:53 UTC (permalink / raw)
  To: daniel; +Cc: ast, viro, ebiederm, tgraf, hannes, netdev, linux-kernel

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 16 Oct 2015 03:09:21 +0200

> This set adds support for persistent maps/progs. Please see
> individual patches for further details.
> 
> A man-page update to bpf(2) will be sent afterwards, also a
> iproute2 patch for support in tc.
> 
> Thanks!

It seems like the design here is still a little bit in flux, so I'm
marking this as "changes requested" in patchwork.

Thanks.

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

* [PATCH net-next 0/4] BPF updates
@ 2015-10-16  1:09 Daniel Borkmann
  2015-10-19  2:53 ` David Miller
  0 siblings, 1 reply; 13+ messages in thread
From: Daniel Borkmann @ 2015-10-16  1:09 UTC (permalink / raw)
  To: davem
  Cc: ast, viro, ebiederm, tgraf, hannes, netdev, linux-kernel,
	Daniel Borkmann

This set adds support for persistent maps/progs. Please see
individual patches for further details.

A man-page update to bpf(2) will be sent afterwards, also a
iproute2 patch for support in tc.

Thanks!

Daniel Borkmann (4):
  bpf: abstract anon_inode_getfd invocations
  bpf: align and clean bpf_{map,prog}_get helpers
  bpf: add support for persistent maps/progs
  bpf: add sample usages for persistent maps/progs

 include/linux/bpf.h        |  23 +-
 include/uapi/linux/bpf.h   |  45 +---
 include/uapi/linux/magic.h |   1 +
 include/uapi/linux/xattr.h |   3 +
 kernel/bpf/Makefile        |   4 +-
 kernel/bpf/inode.c         | 614 +++++++++++++++++++++++++++++++++++++++++++++
 kernel/bpf/syscall.c       | 164 ++++++++++--
 kernel/bpf/verifier.c      |   3 +-
 samples/bpf/Makefile       |   2 +
 samples/bpf/fds_example.c  | 224 +++++++++++++++++
 samples/bpf/libbpf.c       |  20 ++
 samples/bpf/libbpf.h       |   3 +
 12 files changed, 1045 insertions(+), 61 deletions(-)
 create mode 100644 kernel/bpf/inode.c
 create mode 100644 samples/bpf/fds_example.c

-- 
1.9.3

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

* [PATCH net-next 0/4] BPF updates
@ 2015-09-01 16:34 Daniel Borkmann
  0 siblings, 0 replies; 13+ messages in thread
From: Daniel Borkmann @ 2015-09-01 16:34 UTC (permalink / raw)
  To: davem; +Cc: john.fastabend, ast, netdev, Daniel Borkmann

This series adds a couple of improvements to bpf classifier and actions
as well as mqprio. Please see individual patches for details. The series
was still in my queue, I realize it's rather late, so I also don't have
any problem deferring this for the next net-next cycle if it's preferred.

Thanks (also to Alexei for his reviews)!

Daniel Borkmann (3):
  ebpf: migrate bpf_prog's flags to bitfield
  net: {cls,act}_bpf: add helper for retrieving routing realms
  net: {cls,act}_bpf: make skb->priority writable

John Fastabend (1):
  net: qdisc: add op to run filters/actions before enqueue

 arch/arm/net/bpf_jit_32.c       |  2 +-
 arch/arm64/net/bpf_jit_comp.c   |  2 +-
 arch/mips/net/bpf_jit.c         |  2 +-
 arch/powerpc/net/bpf_jit_comp.c |  2 +-
 arch/s390/net/bpf_jit_comp.c    |  2 +-
 arch/sparc/net/bpf_jit_comp.c   |  2 +-
 arch/x86/net/bpf_jit_comp.c     |  2 +-
 include/linux/filter.h          |  7 +++++--
 include/net/sch_generic.h       | 16 +++++++++++-----
 include/uapi/linux/bpf.h        |  7 +++++++
 kernel/bpf/core.c               |  4 ++++
 kernel/bpf/syscall.c            |  6 ++++--
 net/core/dev.c                  | 17 +++++++++++++++++
 net/core/filter.c               | 33 ++++++++++++++++++++++++++++++---
 net/sched/Kconfig               |  5 +++++
 net/sched/cls_bpf.c             |  9 ++++++---
 net/sched/sch_generic.c         |  1 +
 net/sched/sch_mqprio.c          | 35 +++++++++++++++++++++++++++++++++++
 18 files changed, 132 insertions(+), 22 deletions(-)

-- 
1.9.3

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

end of thread, other threads:[~2015-10-19  2:53 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 14:12 [PATCH net-next 0/4] BPF updates Daniel Borkmann
2015-05-06 14:12 ` [PATCH net-next 1/4] net: filter: add a callback to allow classic post-verifier transformations Daniel Borkmann
2015-05-06 15:12   ` Alexei Starovoitov
2015-05-06 14:12 ` [PATCH net-next 2/4] seccomp: simplify seccomp_prepare_filter and reuse bpf_prepare_filter Daniel Borkmann
2015-05-06 15:15   ` Alexei Starovoitov
2015-05-06 14:12 ` [PATCH net-next 3/4] net: filter: add __GFP_NOWARN flag for larger kmem allocs Daniel Borkmann
2015-05-06 15:16   ` Alexei Starovoitov
2015-05-06 14:12 ` [PATCH net-next 4/4] seccomp, filter: add and use bpf_prog_create_from_user from seccomp Daniel Borkmann
2015-05-06 15:21   ` Alexei Starovoitov
2015-05-09 21:33 ` [PATCH net-next 0/4] BPF updates David Miller
2015-09-01 16:34 Daniel Borkmann
2015-10-16  1:09 Daniel Borkmann
2015-10-19  2:53 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).