Skip to content

Commit 5689d49

Browse files
yonghong-songborkmann
authored andcommitted
bpf: Track spill/fill of bounded scalars.
Under register pressure the llvm may spill registers with bounds into the stack. The verifier has to track them through spill/fill otherwise many kinds of bound errors will be seen. The spill/fill of induction variables was already happening. This patch extends this logic from tracking spill/fill of a constant into any bounded register. There is no need to track spill/fill of unbounded, since no new information will be retrieved from the stack during register fill. Though extra stack difference could cause state pruning to be less effective, no adverse affects were seen from this patch on selftests and on cilium programs. Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20201009011240.48506-3-alexei.starovoitov@gmail.com
1 parent 7574883 commit 5689d49

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/bpf/verifier.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,20 @@ static bool register_is_const(struct bpf_reg_state *reg)
22272227
return reg->type == SCALAR_VALUE && tnum_is_const(reg->var_off);
22282228
}
22292229

2230+
static bool __is_scalar_unbounded(struct bpf_reg_state *reg)
2231+
{
2232+
return tnum_is_unknown(reg->var_off) &&
2233+
reg->smin_value == S64_MIN && reg->smax_value == S64_MAX &&
2234+
reg->umin_value == 0 && reg->umax_value == U64_MAX &&
2235+
reg->s32_min_value == S32_MIN && reg->s32_max_value == S32_MAX &&
2236+
reg->u32_min_value == 0 && reg->u32_max_value == U32_MAX;
2237+
}
2238+
2239+
static bool register_is_bounded(struct bpf_reg_state *reg)
2240+
{
2241+
return reg->type == SCALAR_VALUE && !__is_scalar_unbounded(reg);
2242+
}
2243+
22302244
static bool __is_pointer_value(bool allow_ptr_leaks,
22312245
const struct bpf_reg_state *reg)
22322246
{
@@ -2278,7 +2292,7 @@ static int check_stack_write(struct bpf_verifier_env *env,
22782292
if (value_regno >= 0)
22792293
reg = &cur->regs[value_regno];
22802294

2281-
if (reg && size == BPF_REG_SIZE && register_is_const(reg) &&
2295+
if (reg && size == BPF_REG_SIZE && register_is_bounded(reg) &&
22822296
!register_is_null(reg) && env->bpf_capable) {
22832297
if (dst_reg != BPF_REG_FP) {
22842298
/* The backtracking logic can only recognize explicit

0 commit comments

Comments
 (0)