]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
util: check for overflow in get_backoff_delta_msec
authorTobias Stoeckmann <tobias@stoeckmann.org>
Sun, 29 Jun 2025 11:17:22 +0000 (13:17 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Mon, 7 Jul 2025 15:20:33 +0000 (10:20 -0500)
If a large delta is given, the multiplication might overflow.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Link: https://github.com/kmod-project/kmod/pull/377
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
shared/util.c
shared/util.h

index 3d5d179bb09ec0055cccf6cba648822462f4a433..58672a9fc15898ac186cdfbac6d9b5a968d6ecfb 100644 (file)
@@ -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;
        }
index 5a4483ea3974d6a202de632fefc6837d7d4a3ac6..718ecb8a0366b0f83605c84d178c76d1768cbbed 100644 (file)
@@ -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