aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2017-10-16 19:40:54 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-18 09:17:10 -0400
commit00176a34d9e27ab1e77db75fe13abc005cffe0ca (patch)
tree5bc104a145c96a042214e6b7f3e860502cc2bd96
parent7de16e3a35578f4f5accc6f5f23970310483d0a2 (diff)
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>
-rw-r--r--include/linux/bpf.h1
-rw-r--r--include/linux/bpf_verifier.h1
-rw-r--r--kernel/bpf/syscall.c10
-rw-r--r--kernel/bpf/verifier.c23
4 files changed, 18 insertions, 17 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index e1fba5504ca5..cf91977e8719 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -188,7 +188,6 @@ struct bpf_prog_aux {
188 struct latch_tree_node ksym_tnode; 188 struct latch_tree_node ksym_tnode;
189 struct list_head ksym_lnode; 189 struct list_head ksym_lnode;
190 const struct bpf_prog_ops *ops; 190 const struct bpf_prog_ops *ops;
191 const struct bpf_verifier_ops *vops;
192 struct bpf_map **used_maps; 191 struct bpf_map **used_maps;
193 struct bpf_prog *prog; 192 struct bpf_prog *prog;
194 struct user_struct *user; 193 struct user_struct *user;
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index f00ef751c1c5..feeaea93d959 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -141,6 +141,7 @@ struct bpf_ext_analyzer_ops {
141 */ 141 */
142struct bpf_verifier_env { 142struct bpf_verifier_env {
143 struct bpf_prog *prog; /* eBPF program being verified */ 143 struct bpf_prog *prog; /* eBPF program being verified */
144 const struct bpf_verifier_ops *ops;
144 struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */ 145 struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */
145 int stack_size; /* number of states to be processed */ 146 int stack_size; /* number of states to be processed */
146 bool strict_alignment; /* perform strict pointer alignment checks */ 147 bool strict_alignment; /* perform strict pointer alignment checks */
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 444902b5a30d..0e893cac6795 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -748,22 +748,12 @@ static const struct bpf_prog_ops * const bpf_prog_types[] = {
748#undef BPF_MAP_TYPE 748#undef BPF_MAP_TYPE
749}; 749};
750 750
751static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
752#define BPF_PROG_TYPE(_id, _name) \
753 [_id] = & _name ## _verifier_ops,
754#define BPF_MAP_TYPE(_id, _ops)
755#include <linux/bpf_types.h>
756#undef BPF_PROG_TYPE
757#undef BPF_MAP_TYPE
758};
759
760static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) 751static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
761{ 752{
762 if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type]) 753 if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type])
763 return -EINVAL; 754 return -EINVAL;
764 755
765 prog->aux->ops = bpf_prog_types[type]; 756 prog->aux->ops = bpf_prog_types[type];
766 prog->aux->vops = bpf_verifier_ops[type];
767 prog->type = type; 757 prog->type = type;
768 return 0; 758 return 0;
769} 759}
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 38e24d69fc95..3b6e2c550e96 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -23,6 +23,15 @@
23 23
24#include "disasm.h" 24#include "disasm.h"
25 25
26static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
27#define BPF_PROG_TYPE(_id, _name) \
28 [_id] = & _name ## _verifier_ops,
29#define BPF_MAP_TYPE(_id, _ops)
30#include <linux/bpf_types.h>
31#undef BPF_PROG_TYPE
32#undef BPF_MAP_TYPE
33};
34
26/* bpf_check() is a static code analyzer that walks eBPF program 35/* bpf_check() is a static code analyzer that walks eBPF program
27 * instruction by instruction and updates register/stack state. 36 * instruction by instruction and updates register/stack state.
28 * All paths of conditional branches are analyzed until 'bpf_exit' insn. 37 * 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,
856 *reg_type = info.reg_type; 865 *reg_type = info.reg_type;
857 return 0; 866 return 0;
858 } 867 }
859 } else if (env->prog->aux->vops->is_valid_access && 868 } else if (env->ops->is_valid_access &&
860 env->prog->aux->vops->is_valid_access(off, size, t, &info)) { 869 env->ops->is_valid_access(off, size, t, &info)) {
861 /* A non zero info.ctx_field_size indicates that this field is a 870 /* A non zero info.ctx_field_size indicates that this field is a
862 * candidate for later verifier transformation to load the whole 871 * candidate for later verifier transformation to load the whole
863 * field and then apply a mask when accessed with a narrower 872 * 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)
1565 return -EINVAL; 1574 return -EINVAL;
1566 } 1575 }
1567 1576
1568 if (env->prog->aux->vops->get_func_proto) 1577 if (env->ops->get_func_proto)
1569 fn = env->prog->aux->vops->get_func_proto(func_id); 1578 fn = env->ops->get_func_proto(func_id);
1570 1579
1571 if (!fn) { 1580 if (!fn) {
1572 verbose(env, "unknown func %s#%d\n", func_id_name(func_id), 1581 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
4035 */ 4044 */
4036static int convert_ctx_accesses(struct bpf_verifier_env *env) 4045static int convert_ctx_accesses(struct bpf_verifier_env *env)
4037{ 4046{
4038 const struct bpf_verifier_ops *ops = env->prog->aux->vops; 4047 const struct bpf_verifier_ops *ops = env->ops;
4039 int i, cnt, size, ctx_field_size, delta = 0; 4048 int i, cnt, size, ctx_field_size, delta = 0;
4040 const int insn_cnt = env->prog->len; 4049 const int insn_cnt = env->prog->len;
4041 struct bpf_insn insn_buf[16], *insn; 4050 struct bpf_insn insn_buf[16], *insn;
@@ -4236,7 +4245,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
4236 insn = new_prog->insnsi + i + delta; 4245 insn = new_prog->insnsi + i + delta;
4237 } 4246 }
4238patch_call_imm: 4247patch_call_imm:
4239 fn = prog->aux->vops->get_func_proto(insn->imm); 4248 fn = env->ops->get_func_proto(insn->imm);
4240 /* all functions that have prototype and verifier allowed 4249 /* all functions that have prototype and verifier allowed
4241 * programs to call them, must be real in-kernel functions 4250 * programs to call them, must be real in-kernel functions
4242 */ 4251 */
@@ -4294,6 +4303,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
4294 if (!env->insn_aux_data) 4303 if (!env->insn_aux_data)
4295 goto err_free_env; 4304 goto err_free_env;
4296 env->prog = *prog; 4305 env->prog = *prog;
4306 env->ops = bpf_verifier_ops[env->prog->type];
4297 4307
4298 /* grab the mutex to protect few globals used by verifier */ 4308 /* grab the mutex to protect few globals used by verifier */
4299 mutex_lock(&bpf_verifier_lock); 4309 mutex_lock(&bpf_verifier_lock);
@@ -4406,6 +4416,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops,
4406 if (!env->insn_aux_data) 4416 if (!env->insn_aux_data)
4407 goto err_free_env; 4417 goto err_free_env;
4408 env->prog = prog; 4418 env->prog = prog;
4419 env->ops = bpf_verifier_ops[env->prog->type];
4409 env->analyzer_ops = ops; 4420 env->analyzer_ops = ops;
4410 env->analyzer_priv = priv; 4421 env->analyzer_priv = priv;
4411 4422