Skip to content

Commit bd21000

Browse files
KRIISHSHARMAKernel Patches Daemon
authored andcommitted
bpf: verifier: fix WARNING in reg_bounds_sanity_check (2)
syzbot reported a "REG INVARIANTS VIOLATION" triggered in reg_bounds_sanity_check() due to inconsistent umin/umax and var_off state after min/max updates. reg_set_min_max() and adjust_reg_min_max_vals() could leave a register state partially updated before syncing the bounds, causing verifier_bug() to fire. This patch ensures reg_bounds_sync() is called after updates, and additionally marks registers unbounded if min/max values are inconsistent, so that umin/umax, smin/smax, and var_off remain consistent. Fixes: d69eb20 ("Merge tag 'net-6.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net") Reported-by: [email protected] Closes: https://syzkaller.appspot.com/bug?extid=c950cc277150935cc0b5 Signed-off-by: Kriish Sharma <[email protected]>
1 parent 0f635c7 commit bd21000

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

kernel/bpf/verifier.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16318,6 +16318,19 @@ static void regs_refine_cond_op(struct bpf_reg_state *reg1, struct bpf_reg_state
1631816318
}
1631916319
}
1632016320

16321+
/* Ensure that a register's min/max bounds are sane.
16322+
* If any of the unsigned/signed bounds are inconsistent, mark the
16323+
* register as unbounded to prevent verifier invariant violations.
16324+
*/
16325+
static void __maybe_normalize_reg(struct bpf_reg_state *reg)
16326+
{
16327+
if (reg->umin_value > reg->umax_value ||
16328+
reg->smin_value > reg->smax_value ||
16329+
reg->u32_min_value > reg->u32_max_value ||
16330+
reg->s32_min_value > reg->s32_max_value)
16331+
__mark_reg_unbounded(reg);
16332+
}
16333+
1632116334
/* Adjusts the register min/max values in the case that the dst_reg and
1632216335
* src_reg are both SCALAR_VALUE registers (or we are simply doing a BPF_K
1632316336
* check, in which case we have a fake SCALAR_VALUE representing insn->imm).
@@ -16344,11 +16357,15 @@ static int reg_set_min_max(struct bpf_verifier_env *env,
1634416357
regs_refine_cond_op(false_reg1, false_reg2, rev_opcode(opcode), is_jmp32);
1634516358
reg_bounds_sync(false_reg1);
1634616359
reg_bounds_sync(false_reg2);
16360+
__maybe_normalize_reg(false_reg1);
16361+
__maybe_normalize_reg(false_reg2);
1634716362

1634816363
/* jump (TRUE) branch */
1634916364
regs_refine_cond_op(true_reg1, true_reg2, opcode, is_jmp32);
1635016365
reg_bounds_sync(true_reg1);
1635116366
reg_bounds_sync(true_reg2);
16367+
__maybe_normalize_reg(true_reg1);
16368+
__maybe_normalize_reg(true_reg2);
1635216369

1635316370
err = reg_bounds_sanity_check(env, true_reg1, "true_reg1");
1635416371
err = err ?: reg_bounds_sanity_check(env, true_reg2, "true_reg2");

0 commit comments

Comments
 (0)