commit 75a935b5def0bc2fe3e282c643ca5f48fe8c9a90
parent cd8193f4bfaaa2650c2472763ec6bf41ae882539
Author: Rolf Eike Beer <eike@sf-mail.de>
Date: Thu, 26 Dec 2019 20:48:38 +0100
fix possible integer overflow in alloc()
If n is close to 2**32 then the alignment calculation could cause an integer
overflow. Rule this out by checking if the allocation is smaller than the fixed
buffer. It could be done by checking against the possible space, which is done
later anyway, but checking against SPACE has the benefit that this is a
constant.
Diffstat:
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/CHANGES b/CHANGES
@@ -1,3 +1,4 @@
+20191227 fixed possible overflow in alloc() with allocations close to 4GiB
20191226 add missing return types to main()
20190919 fix ipme with multiple addresses on the same interface on platforms
without sa_len
diff --git a/alloc.c b/alloc.c
@@ -10,15 +10,23 @@ static aligned realspace[SPACE / ALIGNMENT];
#define space ((char *) realspace)
static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
+static char *m_alloc(unsigned int n)
+{
+ char *x = malloc(n);
+ if (!x) errno = error_nomem;
+ return x;
+}
+
/*@null@*//*@out@*/char *alloc(n)
unsigned int n;
{
- char *x;
- n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
+ if (n >= SPACE)
+ return m_alloc(n);
+ /* Round it up to the next multiple of alignment. Could overflow if n is
+ * close to 2**32, but by the check above this is already ruled out. */
+ n = ALIGNMENT + n - (n & (ALIGNMENT - 1));
if (n <= avail) { avail -= n; return space + avail; }
- x = malloc(n);
- if (!x) errno = error_nomem;
- return x;
+ return m_alloc(n);
}
void alloc_free(x)