diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-move-fixup_bpf_calls-function.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-move-fixup_bpf_calls-function.patch | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-move-fixup_bpf_calls-function.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-move-fixup_bpf_calls-function.patch new file mode 100644 index 00000000..1da99d50 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-move-fixup_bpf_calls-function.patch @@ -0,0 +1,169 @@ +From c4086a8adedd648b76aa589e5f0c440c61234275 Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov <ast@fb.com> +Date: Wed, 15 Mar 2017 18:26:39 -0700 +Subject: [PATCH 042/102] bpf: move fixup_bpf_calls() function + +commit e245c5c6a5656e4d61aa7bb08e9694fd6e5b2b9d upstream. + +no functional change. +move fixup_bpf_calls() to verifier.c +it's being refactored in the next patch + +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 - gregkh] +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + kernel/bpf/syscall.c | 54 --------------------------------------------------- + kernel/bpf/verifier.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 54 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 237f3d6..6ae783b 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -539,57 +539,6 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl) + list_add(&tl->list_node, &bpf_prog_types); + } + +-/* 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 ... +- * +- * this function is called after eBPF program passed verification +- */ +-static void fixup_bpf_calls(struct bpf_prog *prog) +-{ +- const struct bpf_func_proto *fn; +- int i; +- +- for (i = 0; i < prog->len; i++) { +- struct bpf_insn *insn = &prog->insnsi[i]; +- +- 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; +- } +- +- 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; +- } +- } +-} +- + /* drop refcnt on maps used by eBPF program and free auxilary data */ + static void free_used_maps(struct bpf_prog_aux *aux) + { +@@ -782,9 +731,6 @@ static int bpf_prog_load(union bpf_attr *attr) + if (err < 0) + goto free_used_maps; + +- /* fixup BPF_CALL->imm field */ +- fixup_bpf_calls(prog); +- + /* eBPF program is ready to be JITed */ + prog = bpf_prog_select_runtime(prog, &err); + if (err < 0) +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 85d1c94..b960a3a 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3085,6 +3085,57 @@ 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 ... ++ * ++ * this function is called after eBPF program passed verification ++ */ ++static void fixup_bpf_calls(struct bpf_prog *prog) ++{ ++ const struct bpf_func_proto *fn; ++ int i; ++ ++ for (i = 0; i < prog->len; i++) { ++ struct bpf_insn *insn = &prog->insnsi[i]; ++ ++ 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; ++ } ++ ++ 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; ++ } ++ } ++} ++ + static void free_states(struct bpf_verifier_env *env) + { + struct bpf_verifier_state_list *sl, *sln; +@@ -3183,6 +3234,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) + /* program is valid, convert *(u32*)(ctx + off) accesses */ + ret = convert_ctx_accesses(env); + ++ if (ret == 0) ++ fixup_bpf_calls(env->prog); ++ + if (log_level && log_len >= log_size - 1) { + BUG_ON(log_len >= log_size); + /* verifier log exceeded user supplied buffer */ +-- +2.7.4 + |