On 32bit systems, if you pass a long long to size_add()/mul() the top 32 bits are truncated away so the function doesn't work as expected. Add a test to prevent this.
Signed-off-by: Dan Carpenter <[email protected]> --- include/linux/overflow.h | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 0c7e3dcfe867..e90cd5245497 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -263,7 +263,7 @@ static inline bool __must_check __must_check_overflow(bool overflow) * with any overflow causing the return value to be SIZE_MAX. The * lvalue must be size_t to avoid implicit type conversion. */ -static inline size_t __must_check size_mul(size_t factor1, size_t factor2) +static inline size_t __must_check __size_mul(size_t factor1, size_t factor2) { size_t bytes; @@ -273,6 +273,18 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2) return bytes; } +#define size_mul(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + unsigned long __res; \ + if (UINT_MAX == SIZE_MAX && \ + (__a >= (u64)SIZE_MAX || __b >= (u64)SIZE_MAX)) \ + __res = ULONG_MAX; \ + else \ + __res = __size_mul(__a, __b); \ + __res; \ +}) + /** * size_add() - Calculate size_t addition with saturation at SIZE_MAX * @addend1: first addend @@ -282,7 +294,7 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2) * with any overflow causing the return value to be SIZE_MAX. The * lvalue must be size_t to avoid implicit type conversion. */ -static inline size_t __must_check size_add(size_t addend1, size_t addend2) +static inline size_t __must_check __size_add(size_t addend1, size_t addend2) { size_t bytes; @@ -292,6 +304,18 @@ static inline size_t __must_check size_add(size_t addend1, size_t addend2) return bytes; } +#define size_add(a, b) ({ \ + typeof(a) __a = (a); \ + typeof(b) __b = (b); \ + unsigned long __res; \ + if (UINT_MAX == SIZE_MAX && \ + (__a >= (u64)SIZE_MAX || __b >= (u64)SIZE_MAX)) \ + __res = ULONG_MAX; \ + else \ + __res = __size_add(__a, __b); \ + __res; \ +}) + /** * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX * @minuend: value to subtract from -- 2.45.2
