Skip to content

Commit

Permalink
bpf: Do not mark insn as seen under speculative path verification
Browse files Browse the repository at this point in the history
commit fe9a5ca upstream

... 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 <daniel@iogearbox.net>
Reviewed-by: John Fastabend <john.fastabend@gmail.com>
Reviewed-by: Benedict Schlueter <benedict.schlueter@rub.de>
Reviewed-by: Piotr Krysiuk <piotras@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
[OP: - env->pass_cnt is not used in 5.4, so adjust sanitize_mark_insn_seen()
       to assign "true" instead
     - drop sanitize_insn_aux_data() comment changes, as the function is not
       present in 5.4]
Signed-off-by: Ovidiu Panait <ovidiu.panait@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Daniel Borkmann authored and Greg Kroah-Hartman committed Aug 8, 2021
1 parent 283d742 commit d2f7903
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -4435,6 +4435,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,
Expand Down Expand Up @@ -7790,7 +7803,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);
prev_insn_idx = env->insn_idx;

if (class == BPF_ALU || class == BPF_ALU64) {
Expand Down Expand Up @@ -8025,7 +8038,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;
Expand Down

0 comments on commit d2f7903

Please sign in to comment.