aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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