All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/2] bpf: parallel verification
@ 2019-04-19 14:44 Alexei Starovoitov
  2019-04-19 14:44 ` [PATCH bpf-next 1/2] bpf: remove global variables Alexei Starovoitov
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2019-04-19 14:44 UTC (permalink / raw)
  To: davem; +Cc: daniel, netdev, bpf, kernel-team

Allow the bpf verifier to run in parallel for root.

Alexei Starovoitov (2):
  bpf: remove global variables
  bpf: drop bpf_verifier_lock

 include/linux/bpf_verifier.h |  5 +++++
 kernel/bpf/verifier.c        | 33 ++++++++++++++++++---------------
 2 files changed, 23 insertions(+), 15 deletions(-)

-- 
2.20.0


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

* [PATCH bpf-next 1/2] bpf: remove global variables
  2019-04-19 14:44 [PATCH bpf-next 0/2] bpf: parallel verification Alexei Starovoitov
@ 2019-04-19 14:44 ` Alexei Starovoitov
  2019-04-19 14:44 ` [PATCH bpf-next 2/2] bpf: drop bpf_verifier_lock Alexei Starovoitov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2019-04-19 14:44 UTC (permalink / raw)
  To: davem; +Cc: daniel, netdev, bpf, kernel-team

Move three global variables protected by bpf_verifier_lock into
'struct bpf_verifier_env' to allow parallel verification.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 include/linux/bpf_verifier.h |  5 +++++
 kernel/bpf/verifier.c        | 25 +++++++++++++------------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index b3ab61fe1932..1305ccbd8fe6 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -295,6 +295,11 @@ struct bpf_verifier_env {
 	const struct bpf_line_info *prev_linfo;
 	struct bpf_verifier_log log;
 	struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1];
+	struct {
+		int *insn_state;
+		int *insn_stack;
+		int cur_stack;
+	} cfg;
 	u32 subprog_cnt;
 	/* number of instructions analyzed by the verifier */
 	u32 insn_processed;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index db301e9b5295..5f0eb5bd5589 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5369,10 +5369,6 @@ enum {
 
 #define STATE_LIST_MARK ((struct bpf_verifier_state_list *) -1L)
 
-static int *insn_stack;	/* stack of insns to process */
-static int cur_stack;	/* current stack index */
-static int *insn_state;
-
 /* t, w, e - match pseudo-code above:
  * t - index of current instruction
  * w - next instruction
@@ -5380,6 +5376,9 @@ static int *insn_state;
  */
 static int push_insn(int t, int w, int e, struct bpf_verifier_env *env)
 {
+	int *insn_stack = env->cfg.insn_stack;
+	int *insn_state = env->cfg.insn_state;
+
 	if (e == FALLTHROUGH && insn_state[t] >= (DISCOVERED | FALLTHROUGH))
 		return 0;
 
@@ -5400,9 +5399,9 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env)
 		/* tree-edge */
 		insn_state[t] = DISCOVERED | e;
 		insn_state[w] = DISCOVERED;
-		if (cur_stack >= env->prog->len)
+		if (env->cfg.cur_stack >= env->prog->len)
 			return -E2BIG;
-		insn_stack[cur_stack++] = w;
+		insn_stack[env->cfg.cur_stack++] = w;
 		return 1;
 	} else if ((insn_state[w] & 0xF0) == DISCOVERED) {
 		verbose_linfo(env, t, "%d: ", t);
@@ -5426,14 +5425,15 @@ static int check_cfg(struct bpf_verifier_env *env)
 {
 	struct bpf_insn *insns = env->prog->insnsi;
 	int insn_cnt = env->prog->len;
+	int *insn_stack, *insn_state;
 	int ret = 0;
 	int i, t;
 
-	insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
+	insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
 	if (!insn_state)
 		return -ENOMEM;
 
-	insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
+	insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
 	if (!insn_stack) {
 		kvfree(insn_state);
 		return -ENOMEM;
@@ -5441,12 +5441,12 @@ static int check_cfg(struct bpf_verifier_env *env)
 
 	insn_state[0] = DISCOVERED; /* mark 1st insn as discovered */
 	insn_stack[0] = 0; /* 0 is the first instruction */
-	cur_stack = 1;
+	env->cfg.cur_stack = 1;
 
 peek_stack:
-	if (cur_stack == 0)
+	if (env->cfg.cur_stack == 0)
 		goto check_state;
-	t = insn_stack[cur_stack - 1];
+	t = insn_stack[env->cfg.cur_stack - 1];
 
 	if (BPF_CLASS(insns[t].code) == BPF_JMP ||
 	    BPF_CLASS(insns[t].code) == BPF_JMP32) {
@@ -5515,7 +5515,7 @@ static int check_cfg(struct bpf_verifier_env *env)
 
 mark_explored:
 	insn_state[t] = EXPLORED;
-	if (cur_stack-- <= 0) {
+	if (env->cfg.cur_stack-- <= 0) {
 		verbose(env, "pop stack internal bug\n");
 		ret = -EFAULT;
 		goto err_free;
@@ -5535,6 +5535,7 @@ static int check_cfg(struct bpf_verifier_env *env)
 err_free:
 	kvfree(insn_state);
 	kvfree(insn_stack);
+	env->cfg.insn_state = env->cfg.insn_stack = NULL;
 	return ret;
 }
 
-- 
2.20.0


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

* [PATCH bpf-next 2/2] bpf: drop bpf_verifier_lock
  2019-04-19 14:44 [PATCH bpf-next 0/2] bpf: parallel verification Alexei Starovoitov
  2019-04-19 14:44 ` [PATCH bpf-next 1/2] bpf: remove global variables Alexei Starovoitov
@ 2019-04-19 14:44 ` Alexei Starovoitov
  2019-04-19 19:34 ` [PATCH bpf-next 0/2] bpf: parallel verification Andrii Nakryiko
  2019-04-22 23:58 ` Daniel Borkmann
  3 siblings, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2019-04-19 14:44 UTC (permalink / raw)
  To: davem; +Cc: daniel, netdev, bpf, kernel-team

Drop bpf_verifier_lock for root to avoid being DoS-ed by unprivileged.
The BPF verifier is now fully parallel.
All unpriv users are still serialized by bpf_verifier_lock to avoid
exhausting kernel memory by running N parallel verifications.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/verifier.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5f0eb5bd5589..423f242a5efb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8132,9 +8132,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
 		env->insn_aux_data[i].orig_idx = i;
 	env->prog = *prog;
 	env->ops = bpf_verifier_ops[env->prog->type];
+	is_priv = capable(CAP_SYS_ADMIN);
 
 	/* grab the mutex to protect few globals used by verifier */
-	mutex_lock(&bpf_verifier_lock);
+	if (!is_priv)
+		mutex_lock(&bpf_verifier_lock);
 
 	if (attr->log_level || attr->log_buf || attr->log_size) {
 		/* user requested verbose verifier output
@@ -8157,7 +8159,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
 	if (attr->prog_flags & BPF_F_ANY_ALIGNMENT)
 		env->strict_alignment = false;
 
-	is_priv = capable(CAP_SYS_ADMIN);
 	env->allow_ptr_leaks = is_priv;
 
 	ret = replace_map_fd_with_map_ptr(env);
@@ -8270,7 +8271,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
 		release_maps(env);
 	*prog = env->prog;
 err_unlock:
-	mutex_unlock(&bpf_verifier_lock);
+	if (!is_priv)
+		mutex_unlock(&bpf_verifier_lock);
 	vfree(env->insn_aux_data);
 err_free_env:
 	kfree(env);
-- 
2.20.0


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

* Re: [PATCH bpf-next 0/2] bpf: parallel verification
  2019-04-19 14:44 [PATCH bpf-next 0/2] bpf: parallel verification Alexei Starovoitov
  2019-04-19 14:44 ` [PATCH bpf-next 1/2] bpf: remove global variables Alexei Starovoitov
  2019-04-19 14:44 ` [PATCH bpf-next 2/2] bpf: drop bpf_verifier_lock Alexei Starovoitov
@ 2019-04-19 19:34 ` Andrii Nakryiko
  2019-04-22 23:58 ` Daniel Borkmann
  3 siblings, 0 replies; 6+ messages in thread
From: Andrii Nakryiko @ 2019-04-19 19:34 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: davem, Daniel Borkmann, Networking, bpf, Kernel Team

On Fri, Apr 19, 2019 at 11:24 AM Alexei Starovoitov <ast@kernel.org> wrote:
>
> Allow the bpf verifier to run in parallel for root.
>
> Alexei Starovoitov (2):
>   bpf: remove global variables
>   bpf: drop bpf_verifier_lock
>
>  include/linux/bpf_verifier.h |  5 +++++
>  kernel/bpf/verifier.c        | 33 ++++++++++++++++++---------------
>  2 files changed, 23 insertions(+), 15 deletions(-)
>
> --
> 2.20.0
>
lgtm, for the set:

Acked-by: Andrii Nakryiko <andriin@fb.com>

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

* Re: [PATCH bpf-next 0/2] bpf: parallel verification
  2019-04-19 14:44 [PATCH bpf-next 0/2] bpf: parallel verification Alexei Starovoitov
                   ` (2 preceding siblings ...)
  2019-04-19 19:34 ` [PATCH bpf-next 0/2] bpf: parallel verification Andrii Nakryiko
@ 2019-04-22 23:58 ` Daniel Borkmann
  2019-04-23  0:06   ` Alexei Starovoitov
  3 siblings, 1 reply; 6+ messages in thread
From: Daniel Borkmann @ 2019-04-22 23:58 UTC (permalink / raw)
  To: Alexei Starovoitov, davem; +Cc: netdev, bpf, kernel-team

On 04/19/2019 04:44 PM, Alexei Starovoitov wrote:
> Allow the bpf verifier to run in parallel for root.
> 
> Alexei Starovoitov (2):
>   bpf: remove global variables
>   bpf: drop bpf_verifier_lock
> 
>  include/linux/bpf_verifier.h |  5 +++++
>  kernel/bpf/verifier.c        | 33 ++++++++++++++++++---------------
>  2 files changed, 23 insertions(+), 15 deletions(-)
> 

Too bad we still need to keep it around for unpriv. Anyway, applied, thanks!

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

* Re: [PATCH bpf-next 0/2] bpf: parallel verification
  2019-04-22 23:58 ` Daniel Borkmann
@ 2019-04-23  0:06   ` Alexei Starovoitov
  0 siblings, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2019-04-23  0:06 UTC (permalink / raw)
  To: Daniel Borkmann, Alexei Starovoitov, davem; +Cc: netdev, bpf, Kernel Team

On 4/22/19 4:58 PM, Daniel Borkmann wrote:
> On 04/19/2019 04:44 PM, Alexei Starovoitov wrote:
>> Allow the bpf verifier to run in parallel for root.
>>
>> Alexei Starovoitov (2):
>>    bpf: remove global variables
>>    bpf: drop bpf_verifier_lock
>>
>>   include/linux/bpf_verifier.h |  5 +++++
>>   kernel/bpf/verifier.c        | 33 ++++++++++++++++++---------------
>>   2 files changed, 23 insertions(+), 15 deletions(-)
>>
> 
> Too bad we still need to keep it around for unpriv. Anyway, applied, thanks!

I'm planing to add memcg accounting and teach oom_badness
about the memory used during verification. Then we can drop
the mutex for unpriv as well.

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

end of thread, other threads:[~2019-04-23  0:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-19 14:44 [PATCH bpf-next 0/2] bpf: parallel verification Alexei Starovoitov
2019-04-19 14:44 ` [PATCH bpf-next 1/2] bpf: remove global variables Alexei Starovoitov
2019-04-19 14:44 ` [PATCH bpf-next 2/2] bpf: drop bpf_verifier_lock Alexei Starovoitov
2019-04-19 19:34 ` [PATCH bpf-next 0/2] bpf: parallel verification Andrii Nakryiko
2019-04-22 23:58 ` Daniel Borkmann
2019-04-23  0:06   ` Alexei Starovoitov

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.