Skip to content

Commit 6754172

Browse files
Alexei Starovoitovborkmann
authored andcommitted
bpf: fix precision tracking in presence of bpf2bpf calls
While adding extra tests for precision tracking and extra infra to adjust verifier heuristics the existing test "calls: cross frame pruning - liveness propagation" started to fail. The root cause is the same as described in verifer.c comment: * Also if parent's curframe > frame where backtracking started, * the verifier need to mark registers in both frames, otherwise callees * may incorrectly prune callers. This is similar to * commit 7640ead ("bpf: verifier: make sure callees don't prune with caller differences") * For now backtracking falls back into conservative marking. Turned out though that returning -ENOTSUPP from backtrack_insn() and doing mark_all_scalars_precise() in the current parentage chain is not enough. Depending on how is_state_visited() heuristic is creating parentage chain it's possible that callee will incorrectly prune caller. Fix the issue by setting precise=true earlier and more aggressively. Before this fix the precision tracking _within_ functions that don't do bpf2bpf calls would still work. Whereas now precision tracking is completely disabled when bpf2bpf calls are present anywhere in the program. No difference in cilium tests (they don't have bpf2bpf calls). No difference in test_progs though some of them have bpf2bpf calls, but precision tracking wasn't effective there. Fixes: b5dc016 ("bpf: precise scalar_value tracking") Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent db38de3 commit 6754172

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

kernel/bpf/verifier.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,9 +985,6 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg)
985985
reg->smax_value = S64_MAX;
986986
reg->umin_value = 0;
987987
reg->umax_value = U64_MAX;
988-
989-
/* constant backtracking is enabled for root only for now */
990-
reg->precise = capable(CAP_SYS_ADMIN) ? false : true;
991988
}
992989

993990
/* Mark a register as having a completely unknown (scalar) value. */
@@ -1014,7 +1011,11 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
10141011
__mark_reg_not_init(regs + regno);
10151012
return;
10161013
}
1017-
__mark_reg_unknown(regs + regno);
1014+
regs += regno;
1015+
__mark_reg_unknown(regs);
1016+
/* constant backtracking is enabled for root without bpf2bpf calls */
1017+
regs->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
1018+
true : false;
10181019
}
10191020

10201021
static void __mark_reg_not_init(struct bpf_reg_state *reg)

0 commit comments

Comments
 (0)