diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0043-bpf-refactor-fixup_bpf_calls.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0043-bpf-refactor-fixup_bpf_calls.patch | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0043-bpf-refactor-fixup_bpf_calls.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0043-bpf-refactor-fixup_bpf_calls.patch new file mode 100644 index 00000000..c8b58125 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0043-bpf-refactor-fixup_bpf_calls.patch @@ -0,0 +1,125 @@ +From b0daedd01e01895c380eba49711304ea80df9c2b Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov <ast@fb.com> +Date: Wed, 15 Mar 2017 18:26:40 -0700 +Subject: [PATCH 043/102] bpf: refactor fixup_bpf_calls() + +commit 79741b3bdec01a8628368fbcfccc7d189ed606cb upstream. + +reduce indent and make it iterate over instructions similar to +convert_ctx_accesses(). Also convert hard BUG_ON into soft verifier error. + +Signed-off-by: Alexei Starovoitov <ast@kernel.org> +Acked-by: Daniel Borkmann <daniel@iogearbox.net> +Signed-off-by: David S. Miller <davem@davemloft.net> +Cc: Jiri Slaby <jslaby@suse.cz> +[Backported to 4.9.y - gregkh] +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + kernel/bpf/verifier.c | 73 ++++++++++++++++++++++++--------------------------- + 1 file changed, 34 insertions(+), 39 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index b960a3a..5118d3e 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3085,55 +3085,50 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) + return 0; + } + +-/* fixup insn->imm field of bpf_call instructions: +- * if (insn->imm == BPF_FUNC_map_lookup_elem) +- * insn->imm = bpf_map_lookup_elem - __bpf_call_base; +- * else if (insn->imm == BPF_FUNC_map_update_elem) +- * insn->imm = bpf_map_update_elem - __bpf_call_base; +- * else ... ++/* fixup insn->imm field of bpf_call instructions + * + * this function is called after eBPF program passed verification + */ +-static void fixup_bpf_calls(struct bpf_prog *prog) ++static int fixup_bpf_calls(struct bpf_verifier_env *env) + { ++ struct bpf_prog *prog = env->prog; ++ struct bpf_insn *insn = prog->insnsi; + const struct bpf_func_proto *fn; ++ const int insn_cnt = prog->len; + int i; + +- for (i = 0; i < prog->len; i++) { +- struct bpf_insn *insn = &prog->insnsi[i]; ++ for (i = 0; i < insn_cnt; i++, insn++) { ++ if (insn->code != (BPF_JMP | BPF_CALL)) ++ continue; + +- if (insn->code == (BPF_JMP | BPF_CALL)) { +- /* we reach here when program has bpf_call instructions +- * and it passed bpf_check(), means that +- * ops->get_func_proto must have been supplied, check it +- */ +- BUG_ON(!prog->aux->ops->get_func_proto); +- +- if (insn->imm == BPF_FUNC_get_route_realm) +- prog->dst_needed = 1; +- if (insn->imm == BPF_FUNC_get_prandom_u32) +- bpf_user_rnd_init_once(); +- if (insn->imm == BPF_FUNC_tail_call) { +- /* mark bpf_tail_call as different opcode +- * to avoid conditional branch in +- * interpeter for every normal call +- * and to prevent accidental JITing by +- * JIT compiler that doesn't support +- * bpf_tail_call yet +- */ +- insn->imm = 0; +- insn->code |= BPF_X; +- continue; +- } ++ if (insn->imm == BPF_FUNC_get_route_realm) ++ prog->dst_needed = 1; ++ if (insn->imm == BPF_FUNC_get_prandom_u32) ++ bpf_user_rnd_init_once(); ++ if (insn->imm == BPF_FUNC_tail_call) { ++ /* mark bpf_tail_call as different opcode to avoid ++ * conditional branch in the interpeter for every normal ++ * call and to prevent accidental JITing by JIT compiler ++ * that doesn't support bpf_tail_call yet ++ */ ++ insn->imm = 0; ++ insn->code |= BPF_X; ++ continue; ++ } + +- fn = prog->aux->ops->get_func_proto(insn->imm); +- /* all functions that have prototype and verifier allowed +- * programs to call them, must be real in-kernel functions +- */ +- BUG_ON(!fn->func); +- insn->imm = fn->func - __bpf_call_base; ++ fn = prog->aux->ops->get_func_proto(insn->imm); ++ /* all functions that have prototype and verifier allowed ++ * programs to call them, must be real in-kernel functions ++ */ ++ if (!fn->func) { ++ verbose("kernel subsystem misconfigured func %d\n", ++ insn->imm); ++ return -EFAULT; + } ++ insn->imm = fn->func - __bpf_call_base; + } ++ ++ return 0; + } + + static void free_states(struct bpf_verifier_env *env) +@@ -3235,7 +3230,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) + ret = convert_ctx_accesses(env); + + if (ret == 0) +- fixup_bpf_calls(env->prog); ++ ret = fixup_bpf_calls(env); + + if (log_level && log_len >= log_size - 1) { + BUG_ON(log_len >= log_size); +-- +2.7.4 + |