summaryrefslogtreecommitdiff
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index faf1c8ff243d..1fb0c832611c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -16898,6 +16898,16 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
return err;
}
+ /*
+ * Collect the linked registers before env->{true,false}_reg{1,2} setup,
+ * otherwise ids dropped by collect_linked_regs() would be resurrected
+ * when env->{true,false}_reg{1,2} are copied back.
+ */
+ if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
+ collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
+ if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
+ collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
+
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
env->false_reg1 = *dst_reg;
env->false_reg2 = *src_reg;
@@ -16952,10 +16962,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
* 'this_branch' and 'other_branch' share this history
* if parent state is created.
*/
- if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
- collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
- if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
- collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
if (linked_regs.cnt > 1) {
err = bpf_push_jmp_history(env, this_branch, 0, 0, 0, linked_regs_pack(&linked_regs));
if (err)