Commit 7df737e9 authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by Daniel Borkmann

bpf: remove global variables

Move three global variables protected by bpf_verifier_lock into
'struct bpf_verifier_env' to allow parallel verification.
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 3b880244
...@@ -295,6 +295,11 @@ struct bpf_verifier_env { ...@@ -295,6 +295,11 @@ struct bpf_verifier_env {
const struct bpf_line_info *prev_linfo; const struct bpf_line_info *prev_linfo;
struct bpf_verifier_log log; struct bpf_verifier_log log;
struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1]; struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1];
struct {
int *insn_state;
int *insn_stack;
int cur_stack;
} cfg;
u32 subprog_cnt; u32 subprog_cnt;
/* number of instructions analyzed by the verifier */ /* number of instructions analyzed by the verifier */
u32 insn_processed; u32 insn_processed;
......
...@@ -5369,10 +5369,6 @@ enum { ...@@ -5369,10 +5369,6 @@ enum {
#define STATE_LIST_MARK ((struct bpf_verifier_state_list *) -1L) #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, w, e - match pseudo-code above:
* t - index of current instruction * t - index of current instruction
* w - next instruction * w - next instruction
...@@ -5380,6 +5376,9 @@ static int *insn_state; ...@@ -5380,6 +5376,9 @@ static int *insn_state;
*/ */
static int push_insn(int t, int w, int e, struct bpf_verifier_env *env) 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)) if (e == FALLTHROUGH && insn_state[t] >= (DISCOVERED | FALLTHROUGH))
return 0; return 0;
...@@ -5400,9 +5399,9 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env) ...@@ -5400,9 +5399,9 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env)
/* tree-edge */ /* tree-edge */
insn_state[t] = DISCOVERED | e; insn_state[t] = DISCOVERED | e;
insn_state[w] = DISCOVERED; insn_state[w] = DISCOVERED;
if (cur_stack >= env->prog->len) if (env->cfg.cur_stack >= env->prog->len)
return -E2BIG; return -E2BIG;
insn_stack[cur_stack++] = w; insn_stack[env->cfg.cur_stack++] = w;
return 1; return 1;
} else if ((insn_state[w] & 0xF0) == DISCOVERED) { } else if ((insn_state[w] & 0xF0) == DISCOVERED) {
verbose_linfo(env, t, "%d: ", t); verbose_linfo(env, t, "%d: ", t);
...@@ -5426,14 +5425,15 @@ static int check_cfg(struct bpf_verifier_env *env) ...@@ -5426,14 +5425,15 @@ static int check_cfg(struct bpf_verifier_env *env)
{ {
struct bpf_insn *insns = env->prog->insnsi; struct bpf_insn *insns = env->prog->insnsi;
int insn_cnt = env->prog->len; int insn_cnt = env->prog->len;
int *insn_stack, *insn_state;
int ret = 0; int ret = 0;
int i, t; 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) if (!insn_state)
return -ENOMEM; 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) { if (!insn_stack) {
kvfree(insn_state); kvfree(insn_state);
return -ENOMEM; return -ENOMEM;
...@@ -5441,12 +5441,12 @@ static int check_cfg(struct bpf_verifier_env *env) ...@@ -5441,12 +5441,12 @@ static int check_cfg(struct bpf_verifier_env *env)
insn_state[0] = DISCOVERED; /* mark 1st insn as discovered */ insn_state[0] = DISCOVERED; /* mark 1st insn as discovered */
insn_stack[0] = 0; /* 0 is the first instruction */ insn_stack[0] = 0; /* 0 is the first instruction */
cur_stack = 1; env->cfg.cur_stack = 1;
peek_stack: peek_stack:
if (cur_stack == 0) if (env->cfg.cur_stack == 0)
goto check_state; 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 || if (BPF_CLASS(insns[t].code) == BPF_JMP ||
BPF_CLASS(insns[t].code) == BPF_JMP32) { BPF_CLASS(insns[t].code) == BPF_JMP32) {
...@@ -5515,7 +5515,7 @@ static int check_cfg(struct bpf_verifier_env *env) ...@@ -5515,7 +5515,7 @@ static int check_cfg(struct bpf_verifier_env *env)
mark_explored: mark_explored:
insn_state[t] = EXPLORED; insn_state[t] = EXPLORED;
if (cur_stack-- <= 0) { if (env->cfg.cur_stack-- <= 0) {
verbose(env, "pop stack internal bug\n"); verbose(env, "pop stack internal bug\n");
ret = -EFAULT; ret = -EFAULT;
goto err_free; goto err_free;
...@@ -5535,6 +5535,7 @@ static int check_cfg(struct bpf_verifier_env *env) ...@@ -5535,6 +5535,7 @@ static int check_cfg(struct bpf_verifier_env *env)
err_free: err_free:
kvfree(insn_state); kvfree(insn_state);
kvfree(insn_stack); kvfree(insn_stack);
env->cfg.insn_state = env->cfg.insn_stack = NULL;
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment