Skip to content

Commit

Permalink
bpf: remove the verifier ops from program structure
Browse files Browse the repository at this point in the history
Since the verifier ops don't have to be associated with
the program for its entire lifetime we can move it to
verifier's struct bpf_verifier_env.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Oct 18, 2017
1 parent 7de16e3 commit 00176a3
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 17 deletions.
1 change: 0 additions & 1 deletion include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ struct bpf_prog_aux {
struct latch_tree_node ksym_tnode;
struct list_head ksym_lnode;
const struct bpf_prog_ops *ops;
const struct bpf_verifier_ops *vops;
struct bpf_map **used_maps;
struct bpf_prog *prog;
struct user_struct *user;
Expand Down
1 change: 1 addition & 0 deletions include/linux/bpf_verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ struct bpf_ext_analyzer_ops {
*/
struct bpf_verifier_env {
struct bpf_prog *prog; /* eBPF program being verified */
const struct bpf_verifier_ops *ops;
struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */
int stack_size; /* number of states to be processed */
bool strict_alignment; /* perform strict pointer alignment checks */
Expand Down
10 changes: 0 additions & 10 deletions kernel/bpf/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,22 +748,12 @@ static const struct bpf_prog_ops * const bpf_prog_types[] = {
#undef BPF_MAP_TYPE
};

static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name) \
[_id] = & _name ## _verifier_ops,
#define BPF_MAP_TYPE(_id, _ops)
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE
};

static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
{
if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type])
return -EINVAL;

prog->aux->ops = bpf_prog_types[type];
prog->aux->vops = bpf_verifier_ops[type];
prog->type = type;
return 0;
}
Expand Down
23 changes: 17 additions & 6 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@

#include "disasm.h"

static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name) \
[_id] = & _name ## _verifier_ops,
#define BPF_MAP_TYPE(_id, _ops)
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
#undef BPF_MAP_TYPE
};

/* bpf_check() is a static code analyzer that walks eBPF program
* instruction by instruction and updates register/stack state.
* All paths of conditional branches are analyzed until 'bpf_exit' insn.
Expand Down Expand Up @@ -856,8 +865,8 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
*reg_type = info.reg_type;
return 0;
}
} else if (env->prog->aux->vops->is_valid_access &&
env->prog->aux->vops->is_valid_access(off, size, t, &info)) {
} else if (env->ops->is_valid_access &&
env->ops->is_valid_access(off, size, t, &info)) {
/* A non zero info.ctx_field_size indicates that this field is a
* candidate for later verifier transformation to load the whole
* field and then apply a mask when accessed with a narrower
Expand Down Expand Up @@ -1565,8 +1574,8 @@ static int check_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
return -EINVAL;
}

if (env->prog->aux->vops->get_func_proto)
fn = env->prog->aux->vops->get_func_proto(func_id);
if (env->ops->get_func_proto)
fn = env->ops->get_func_proto(func_id);

if (!fn) {
verbose(env, "unknown func %s#%d\n", func_id_name(func_id),
Expand Down Expand Up @@ -4035,7 +4044,7 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of
*/
static int convert_ctx_accesses(struct bpf_verifier_env *env)
{
const struct bpf_verifier_ops *ops = env->prog->aux->vops;
const struct bpf_verifier_ops *ops = env->ops;
int i, cnt, size, ctx_field_size, delta = 0;
const int insn_cnt = env->prog->len;
struct bpf_insn insn_buf[16], *insn;
Expand Down Expand Up @@ -4236,7 +4245,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
insn = new_prog->insnsi + i + delta;
}
patch_call_imm:
fn = prog->aux->vops->get_func_proto(insn->imm);
fn = env->ops->get_func_proto(insn->imm);
/* all functions that have prototype and verifier allowed
* programs to call them, must be real in-kernel functions
*/
Expand Down Expand Up @@ -4294,6 +4303,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
if (!env->insn_aux_data)
goto err_free_env;
env->prog = *prog;
env->ops = bpf_verifier_ops[env->prog->type];

/* grab the mutex to protect few globals used by verifier */
mutex_lock(&bpf_verifier_lock);
Expand Down Expand Up @@ -4406,6 +4416,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops,
if (!env->insn_aux_data)
goto err_free_env;
env->prog = prog;
env->ops = bpf_verifier_ops[env->prog->type];
env->analyzer_ops = ops;
env->analyzer_priv = priv;

Expand Down

0 comments on commit 00176a3

Please sign in to comment.