bpf: remove the verifier ops from program structure
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>
This commit is contained in:
Родитель
7de16e3a35
Коммит
00176a34d9
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче