bpf/verifier: when pruning a branch, ignore its write marks
The fact that writes occurred in reaching the continuation state does
not screen off its reads from us, because we're not really its parent.
So detect 'not really the parent' in do_propagate_liveness, and ignore
write marks in that case.
Fixes: dc503a8ad9
("bpf/verifier: track liveness for pruning")
Signed-off-by: Edward Cree <ecree@solarflare.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d893dc26e3
commit
63f45f8406
|
@ -3436,6 +3436,7 @@ static bool states_equal(struct bpf_verifier_env *env,
|
|||
static bool do_propagate_liveness(const struct bpf_verifier_state *state,
|
||||
struct bpf_verifier_state *parent)
|
||||
{
|
||||
bool writes = parent == state->parent; /* Observe write marks */
|
||||
bool touched = false; /* any changes made? */
|
||||
int i;
|
||||
|
||||
|
@ -3447,7 +3448,9 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state,
|
|||
for (i = 0; i < BPF_REG_FP; i++) {
|
||||
if (parent->regs[i].live & REG_LIVE_READ)
|
||||
continue;
|
||||
if (state->regs[i].live == REG_LIVE_READ) {
|
||||
if (writes && (state->regs[i].live & REG_LIVE_WRITTEN))
|
||||
continue;
|
||||
if (state->regs[i].live & REG_LIVE_READ) {
|
||||
parent->regs[i].live |= REG_LIVE_READ;
|
||||
touched = true;
|
||||
}
|
||||
|
@ -3460,7 +3463,9 @@ static bool do_propagate_liveness(const struct bpf_verifier_state *state,
|
|||
continue;
|
||||
if (parent->spilled_regs[i].live & REG_LIVE_READ)
|
||||
continue;
|
||||
if (state->spilled_regs[i].live == REG_LIVE_READ) {
|
||||
if (writes && (state->spilled_regs[i].live & REG_LIVE_WRITTEN))
|
||||
continue;
|
||||
if (state->spilled_regs[i].live & REG_LIVE_READ) {
|
||||
parent->spilled_regs[i].live |= REG_LIVE_READ;
|
||||
touched = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue