bpf: Check the iteration count before the predicted exit value

The comment before `total_change` computation:

    /*
     * compute_backedge_taken_count() guarantees that 'total_change'
     * does not overflow in 64-bit domain.
     */
    total_change = initial + step * backedge_taken_count;

Is not true before the check:

    if (backedge_taken_count >= U32_MAX - 1)
        return false;

Move the check before `total_change` computation in order to reconcile
the code with comments. Old position is not a bug the check was
performed either way.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261026-scev-simpler-clamp-v2-4-f373aec9825f@gmail.com
This commit is contained in:
Eduard Zingerman 2026-10-26 16:38:24 -07:00 committed by Alexei Starovoitov
parent 5dd32c8c10
commit 86d654957d
No known key found for this signature in database

View File

@ -2307,11 +2307,15 @@ static bool compute_max_iters(struct bpf_verifier_env *env,
if (!compute_backedge_taken_count(op, initial, step, bound, &backedge_taken_count))
return false;
/*
* max_header_count is u32 and U32_MAX means "infinite",
* check to avoid overflow below.
*/
if (backedge_taken_count >= U32_MAX - 1)
return false;
if (latch->zext32 || latch->jmp32) {
/*
* compute_backedge_taken_count() guarantees that 'total_change'
* does not overflow in 64-bit domain.
*/
/* total_change is guaranteed not to overflow at this point */
total_change = initial + step * backedge_taken_count;
if (latch->jmp32 && is_signed_op(op)) {
if ((s64)total_change < S32_MIN || (s64)total_change > S32_MAX)
@ -2322,13 +2326,6 @@ static bool compute_max_iters(struct bpf_verifier_env *env,
}
}
/*
* max_header_count is u32 and U32_MAX means "infinite",
* check to avoid overflow below.
*/
if (backedge_taken_count >= U32_MAX - 1)
return false;
/* The header executes once on entry and once for each taken backedge, hence +1. */
iters->max_header_count = backedge_taken_count + 1;
/*