From: Daniel Borkmann
mainline inclusion
from mainline-v5.13-rc7
commit fe9a5ca7e370e613a9a75a13008a3845ea759d6e
category: bugfix
issue: #I42H19
CVE: CVE-2021-33624
--------------------------------
... in such circumstances, we do not want to mark the instruction as seen given
the goal is still to jmp-1 rewrite/sanitize dead code, if it is not reachable
from the non-speculative path verification. We do however want to verify it for
safety regardless.
With the patch as-is all the insns that have been marked as seen before the
patch will also be marked as seen after the patch (just with a potentially
different non-zero count). An upcoming patch will also verify paths that are
unreachable in the non-speculative domain, hence this extension is needed.
Signed-off-by: Daniel Borkmann
Reviewed-by: John Fastabend
Reviewed-by: Benedict Schlueter
Reviewed-by: Piotr Krysiuk
Acked-by: Alexei Starovoitov
Conflicts:
kernel/bpf/verifier.c
pass_cnt is not introduced in kernel-4.19.
Signed-off-by: He Fengqing
Reviewed-by: Kuohai Xu
Reviewed-by: Xiu Jianfeng
Signed-off-by: Yang Yingliang
Signed-off-by: Yu Changchun
---
kernel/bpf/verifier.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 59027b765..7f3734b61 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2901,6 +2901,19 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
return !ret ? REASON_STACK : 0;
}
+static void sanitize_mark_insn_seen(struct bpf_verifier_env *env)
+{
+ struct bpf_verifier_state *vstate = env->cur_state;
+
+ /* If we simulate paths under speculation, we don't update the
+ * insn as 'seen' such that when we verify unreachable paths in
+ * the non-speculative domain, sanitize_dead_code() can still
+ * rewrite/sanitize them.
+ */
+ if (!vstate->speculative)
+ env->insn_aux_data[env->insn_idx].seen = true;
+}
+
static int sanitize_err(struct bpf_verifier_env *env,
const struct bpf_insn *insn, int reason,
const struct bpf_reg_state *off_reg,
@@ -5442,7 +5455,7 @@ static int do_check(struct bpf_verifier_env *env)
}
regs = cur_regs(env);
- env->insn_aux_data[env->insn_idx].seen = true;
+ sanitize_mark_insn_seen(env);
if (class == BPF_ALU || class == BPF_ALU64) {
err = check_alu_op(env, insn);
@@ -5663,7 +5676,7 @@ static int do_check(struct bpf_verifier_env *env)
return err;
env->insn_idx++;
- env->insn_aux_data[env->insn_idx].seen = true;
+ sanitize_mark_insn_seen(env);
} else {
verbose(env, "invalid BPF_LD mode\n");
return -EINVAL;
--
2.22.0