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>
} 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;
}
#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