summaryrefslogtreecommitdiff
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2018-05-03 16:49:21 -0700
committerAlexei Starovoitov <ast@kernel.org>2018-05-03 16:49:22 -0700
commit5234ccf2be0e51b2cd052fe5e2fcc978e67aebc7 (patch)
tree92221b6309ccd5c231dde62a2a7ca1d21cbca9fe /kernel/bpf/verifier.c
parent08dbc7a66af2321661173c04d872eba44003cc13 (diff)
parent32b3652c307ef62f624182fac1fd6328ccc8fcbe (diff)
Merge branch 'move-ld_abs-to-native-BPF'
Daniel Borkmann says: ==================== This set simplifies BPF JITs significantly by moving ld_abs/ld_ind to native BPF, for details see individual patches. Main rationale is in patch 'implement ld_abs/ld_ind in native bpf'. Thanks! v1 -> v2: - Added missing seen_lds_abs in LDX_MSH and use X = A initially due to being preserved on func call. - Added a large batch of cBPF tests into test_bpf. - Added x32 removal of LD_ABS/LD_IND, so all JITs are covered. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0d91f18b2eb5..6ba10a83909d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3884,6 +3884,11 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
return -EINVAL;
}
+ if (!env->ops->gen_ld_abs) {
+ verbose(env, "bpf verifier is misconfigured\n");
+ return -EINVAL;
+ }
+
if (env->subprog_cnt) {
/* when program has LD_ABS insn JITs and interpreter assume
* that r1 == ctx == skb which is not the case for callees
@@ -5519,6 +5524,25 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
continue;
}
+ if (BPF_CLASS(insn->code) == BPF_LD &&
+ (BPF_MODE(insn->code) == BPF_ABS ||
+ BPF_MODE(insn->code) == BPF_IND)) {
+ cnt = env->ops->gen_ld_abs(insn, insn_buf);
+ if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf)) {
+ verbose(env, "bpf verifier is misconfigured\n");
+ return -EINVAL;
+ }
+
+ new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
+ if (!new_prog)
+ return -ENOMEM;
+
+ delta += cnt - 1;
+ env->prog = prog = new_prog;
+ insn = new_prog->insnsi + i + delta;
+ continue;
+ }
+
if (insn->code != (BPF_JMP | BPF_CALL))
continue;
if (insn->src_reg == BPF_PSEUDO_CALL)