From: Tobias Stoeckmann Date: Sun, 29 Jun 2025 11:17:22 +0000 (+0200) Subject: util: check for overflow in get_backoff_delta_msec X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=65afd0f1c6c7128a6166aed8096390c0649f5fe5;p=thirdparty%2Fkmod.git util: check for overflow in get_backoff_delta_msec If a large delta is given, the multiplication might overflow. Signed-off-by: Tobias Stoeckmann Link: https://github.com/kmod-project/kmod/pull/377 Signed-off-by: Lucas De Marchi --- diff --git a/shared/util.c b/shared/util.c index 3d5d179b..58672a9f 100644 --- a/shared/util.c +++ b/shared/util.c @@ -546,14 +546,17 @@ unsigned long long get_backoff_delta_msec(unsigned long long tend, } else { const unsigned long long limit = tend - t; + /* Double the amount of requested delta, if possible */ if (!*delta) *delta = 1; - else - *delta <<= 1; + else if (umulll_overflow(*delta, 2, delta)) + *delta = ULLONG_MAX; + /* Search for a fitting backoff delta */ while (*delta > limit) *delta >>= 1; + /* If none found, use maximum wait time */ if (!*delta) *delta = limit; } diff --git a/shared/util.h b/shared/util.h index 5a4483ea..718ecb8a 100644 --- a/shared/util.h +++ b/shared/util.h @@ -151,6 +151,17 @@ static inline bool umul64_overflow(uint64_t a, uint64_t b, uint64_t *res) #endif } +static inline bool umulll_overflow(unsigned long long a, unsigned long long b, + unsigned long long *res) +{ +#if (HAVE___BUILTIN_UMULLL_OVERFLOW) + return __builtin_umulll_overflow(a, b, res); +#else + *res = a * b; + return UINT64_MAX / a < b; +#endif +} + static inline bool umulsz_overflow(size_t a, size_t b, size_t *res) { #if __SIZEOF_SIZE_T__ == 8