[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <ebdae636-11f3-4f02-a158-f15bbed2847f@stanley.mountain>
Date: Mon, 18 Nov 2024 09:09:28 +0300
From: Dan Carpenter <dan.carpenter@...aro.org>
To: Kees Cook <kees@...nel.org>
Cc: "Gustavo A. R. Silva" <gustavoars@...nel.org>,
linux-hardening@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH] overflow: improve size_add/mul for 32bit systems
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 <dan.carpenter@...aro.org>
---
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
Powered by blists - more mailing lists