bpf: Factor out visit_func_call_insn() in check_cfg()
authorYonghong Song <yhs@fb.com>
Fri, 26 Feb 2021 20:49:20 +0000 (12:49 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 26 Feb 2021 21:23:52 +0000 (13:23 -0800)
During verifier check_cfg(), all instructions are
visited to ensure verifier can handle program control flows.
This patch factored out function visit_func_call_insn()
so it can be reused in later patch to visit callback function
calls. There is no functionality change for this patch.

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210226204920.3884136-1-yhs@fb.com
kernel/bpf/verifier.c

index 9336bac..b14fab7 100644 (file)
@@ -8592,6 +8592,27 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env,
        return DONE_EXPLORING;
 }
 
+static int visit_func_call_insn(int t, int insn_cnt,
+                               struct bpf_insn *insns,
+                               struct bpf_verifier_env *env,
+                               bool visit_callee)
+{
+       int ret;
+
+       ret = push_insn(t, t + 1, FALLTHROUGH, env, false);
+       if (ret)
+               return ret;
+
+       if (t + 1 < insn_cnt)
+               init_explored_state(env, t + 1);
+       if (visit_callee) {
+               init_explored_state(env, t);
+               ret = push_insn(t, t + insns[t].imm + 1, BRANCH,
+                               env, false);
+       }
+       return ret;
+}
+
 /* Visits the instruction at index t and returns one of the following:
  *  < 0 - an error occurred
  *  DONE_EXPLORING - the instruction was fully explored
@@ -8612,18 +8633,8 @@ static int visit_insn(int t, int insn_cnt, struct bpf_verifier_env *env)
                return DONE_EXPLORING;
 
        case BPF_CALL:
-               ret = push_insn(t, t + 1, FALLTHROUGH, env, false);
-               if (ret)
-                       return ret;
-
-               if (t + 1 < insn_cnt)
-                       init_explored_state(env, t + 1);
-               if (insns[t].src_reg == BPF_PSEUDO_CALL) {
-                       init_explored_state(env, t);
-                       ret = push_insn(t, t + insns[t].imm + 1, BRANCH,
-                                       env, false);
-               }
-               return ret;
+               return visit_func_call_insn(t, insn_cnt, insns, env,
+                                           insns[t].src_reg == BPF_PSEUDO_CALL);
 
        case BPF_JA:
                if (BPF_SRC(insns[t].code) != BPF_K)