diff --git a/kernel/bpf/cnum_defs.h b/kernel/bpf/cnum_defs.h index 3ebd8f723dbb..af1f13c58903 100644 --- a/kernel/bpf/cnum_defs.h +++ b/kernel/bpf/cnum_defs.h @@ -220,6 +220,17 @@ bool FN(is_const)(struct cnum_t cnum) return cnum.size == 0; } +bool FN(is_within)(struct cnum_t outer, struct cnum_t inner) +{ + if (FN(is_empty)(outer) || FN(is_empty(inner))) + return false; + if (outer.size == UT_MAX) + return true; + inner.base -= outer.base; + outer.base = 0; + return !FN(urange_overflow)(inner) && inner.base + inner.size <= outer.size; +} + #undef EMPTY #undef cnum_t #undef ut diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c index a78ae891b743..e06c07981945 100644 --- a/kernel/bpf/states.c +++ b/kernel/bpf/states.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ +#include "linux/cnum.h" #include #include #include @@ -301,14 +302,8 @@ int bpf_update_branch_counts(struct bpf_verifier_env *env, struct bpf_verifier_s static bool range_within(const struct bpf_reg_state *old, const struct bpf_reg_state *cur) { - return reg_umin(old) <= reg_umin(cur) && - reg_umax(old) >= reg_umax(cur) && - reg_smin(old) <= reg_smin(cur) && - reg_smax(old) >= reg_smax(cur) && - reg_u32_min(old) <= reg_u32_min(cur) && - reg_u32_max(old) >= reg_u32_max(cur) && - reg_s32_min(old) <= reg_s32_min(cur) && - reg_s32_max(old) >= reg_s32_max(cur); + return cnum64_is_within(old->r64, cur->r64) && + cnum32_is_within(old->r32, cur->r32); } /* If in the old state two registers had the same id, then they need to have