diff options
-rw-r--r-- | include/linux/bpf.h | 1 | ||||
-rw-r--r-- | include/linux/bpf_verifier.h | 1 | ||||
-rw-r--r-- | kernel/bpf/syscall.c | 10 | ||||
-rw-r--r-- | kernel/bpf/verifier.c | 23 |
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 | */ |
142 | struct bpf_verifier_env { | 142 | struct 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 | ||
751 | static 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 | |||
760 | static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog) | 751 | static 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 | ||
26 | static 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 | */ |
4036 | static int convert_ctx_accesses(struct bpf_verifier_env *env) | 4045 | static 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 | } |
4238 | patch_call_imm: | 4247 | patch_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 | ||