mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-19 13:11:14 +00:00
bpf: Do not mark insn as seen under speculative path verification
... 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>
This commit is contained in:
parent
d203b0fd86
commit
fe9a5ca7e3
1 changed files with 18 additions and 2 deletions
|
@ -6572,6 +6572,19 @@ do_sim:
|
||||||
return !ret ? REASON_STACK : 0;
|
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 = env->pass_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
static int sanitize_err(struct bpf_verifier_env *env,
|
static int sanitize_err(struct bpf_verifier_env *env,
|
||||||
const struct bpf_insn *insn, int reason,
|
const struct bpf_insn *insn, int reason,
|
||||||
const struct bpf_reg_state *off_reg,
|
const struct bpf_reg_state *off_reg,
|
||||||
|
@ -10630,7 +10643,7 @@ static int do_check(struct bpf_verifier_env *env)
|
||||||
}
|
}
|
||||||
|
|
||||||
regs = cur_regs(env);
|
regs = cur_regs(env);
|
||||||
env->insn_aux_data[env->insn_idx].seen = env->pass_cnt;
|
sanitize_mark_insn_seen(env);
|
||||||
prev_insn_idx = env->insn_idx;
|
prev_insn_idx = env->insn_idx;
|
||||||
|
|
||||||
if (class == BPF_ALU || class == BPF_ALU64) {
|
if (class == BPF_ALU || class == BPF_ALU64) {
|
||||||
|
@ -10857,7 +10870,7 @@ process_bpf_exit:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
env->insn_idx++;
|
env->insn_idx++;
|
||||||
env->insn_aux_data[env->insn_idx].seen = env->pass_cnt;
|
sanitize_mark_insn_seen(env);
|
||||||
} else {
|
} else {
|
||||||
verbose(env, "invalid BPF_LD mode\n");
|
verbose(env, "invalid BPF_LD mode\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -12712,6 +12725,9 @@ static void free_states(struct bpf_verifier_env *env)
|
||||||
* insn_aux_data was touched. These variables are compared to clear temporary
|
* insn_aux_data was touched. These variables are compared to clear temporary
|
||||||
* data from failed pass. For testing and experiments do_check_common() can be
|
* data from failed pass. For testing and experiments do_check_common() can be
|
||||||
* run multiple times even when prior attempt to verify is unsuccessful.
|
* run multiple times even when prior attempt to verify is unsuccessful.
|
||||||
|
*
|
||||||
|
* Note that special handling is needed on !env->bypass_spec_v1 if this is
|
||||||
|
* ever called outside of error path with subsequent program rejection.
|
||||||
*/
|
*/
|
||||||
static void sanitize_insn_aux_data(struct bpf_verifier_env *env)
|
static void sanitize_insn_aux_data(struct bpf_verifier_env *env)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue