Commit 52c2b005 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

bpf: take into account liveness when propagating precision

When doing state comparison, if old state has register that is not
marked as REG_LIVE_READ, then we just skip comparison, regardless what's
the state of corresponing register in current state. This is because not
REG_LIVE_READ register is irrelevant for further program execution and
correctness. All good here.

But when we get to precision propagation, after two states were declared
equivalent, we don't take into account old register's liveness, and thus
attempt to propagate precision for register in current state even if
that register in old state was not REG_LIVE_READ anymore. This is bad,
because register in current state could be anything at all and this
could cause -EFAULT due to internal logic bugs.

Fix by taking into account REG_LIVE_READ liveness mark to keep the logic
in state comparison in sync with precision propagation.

Fixes: a3ce685d ("bpf: fix precision tracking")
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20230309224131.57449-1-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 4b5ce570
...@@ -15058,7 +15058,8 @@ static int propagate_precision(struct bpf_verifier_env *env, ...@@ -15058,7 +15058,8 @@ static int propagate_precision(struct bpf_verifier_env *env,
state_reg = state->regs; state_reg = state->regs;
for (i = 0; i < BPF_REG_FP; i++, state_reg++) { for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
if (state_reg->type != SCALAR_VALUE || if (state_reg->type != SCALAR_VALUE ||
!state_reg->precise) !state_reg->precise ||
!(state_reg->live & REG_LIVE_READ))
continue; continue;
if (env->log.level & BPF_LOG_LEVEL2) if (env->log.level & BPF_LOG_LEVEL2)
verbose(env, "frame %d: propagating r%d\n", i, fr); verbose(env, "frame %d: propagating r%d\n", i, fr);
...@@ -15072,7 +15073,8 @@ static int propagate_precision(struct bpf_verifier_env *env, ...@@ -15072,7 +15073,8 @@ static int propagate_precision(struct bpf_verifier_env *env,
continue; continue;
state_reg = &state->stack[i].spilled_ptr; state_reg = &state->stack[i].spilled_ptr;
if (state_reg->type != SCALAR_VALUE || if (state_reg->type != SCALAR_VALUE ||
!state_reg->precise) !state_reg->precise ||
!(state_reg->live & REG_LIVE_READ))
continue; continue;
if (env->log.level & BPF_LOG_LEVEL2) if (env->log.level & BPF_LOG_LEVEL2)
verbose(env, "frame %d: propagating fp%d\n", verbose(env, "frame %d: propagating fp%d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment