From: Alexei Starovoitov <a...@fb.com>

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 <a...@kernel.org>
Acked-by: Daniel Borkmann <dan...@iogearbox.net>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Jiri Slaby <jsl...@suse.cz>
---
 kernel/bpf/verifier.c | 72 +++++++++++++++++++++++----------------------------
 1 file changed, 33 insertions(+), 39 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 198737d36754..47bb3eee950c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2158,57 +2158,51 @@ static int convert_ctx_accesses(struct 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 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
+               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
                         */
-                       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;
-                       }
+                       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 verifier_env *env)
 {
@@ -2309,7 +2303,7 @@ skip_full_check:
                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.15.1

Reply via email to