summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-03-29 23:02:34 +0200
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-04-28 00:40:42 +0200
commitf9c58fb385343b8e3fa13988efcbd30ae3285ea7 (patch)
tree71c2e23517f5cdafbc99eacb3923c0950f463cdb
parent71585e8fcb8704a9f431f5a8d019280cccaad069 (diff)
downloadexim4-f9c58fb385343b8e3fa13988efcbd30ae3285ea7.tar.gz
SECURITY: Refuse negative and large store allocations
Based on Phil Pennock's commits b34d3046 and e6c1606a. Done by Qualys. (cherry picked from commit 09d36bd64fc5bf71d8882af35c41ac4e8599acc1)
-rw-r--r--src/src/store.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/src/store.c b/src/src/store.c
index 305ae6334..123df70ee 100644
--- a/src/src/store.c
+++ b/src/src/store.c
@@ -239,12 +239,10 @@ A zero size might be also suspect, but our internal usage deliberately
does this to return a current watermark value for a later release of
allocated store. */
-if (size < 0)
- {
+if (size < 0 || size >= INT_MAX/2)
log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"bad memory allocation requested (%d bytes) at %s %d",
size, func, linenumber);
- }
/* Round up the size to a multiple of the alignment. Although this looks a
messy statement, because "alignment" is a constant expression, the compiler can
@@ -392,12 +390,10 @@ int pool = tainted ? store_pool + POOL_TAINT_BASE : store_pool;
int inc = newsize - oldsize;
int rounded_oldsize = oldsize;
-if (newsize < 0)
- {
+if (oldsize < 0 || newsize < oldsize || newsize >= INT_MAX/2)
log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"bad memory extension requested (%d -> %d bytes) at %s %d",
oldsize, newsize, func, linenumber);
- }
/* Check that the block being extended was already of the required taint status;
refuse to extend if not. */
@@ -759,6 +755,11 @@ if (is_tainted(block) != tainted)
die_tainted(US"store_newblock", CUS func, linenumber);
#endif
+if (len < 0 || len > newsize)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+ "bad memory extension requested (%d -> %d bytes) at %s %d",
+ len, newsize, func, linenumber);
+
newtext = store_get(newsize, tainted);
memcpy(newtext, block, len);
if (release_ok) store_release_3(block, pool, func, linenumber);
@@ -789,6 +790,11 @@ internal_store_malloc(int size, const char *func, int line)
{
void * yield;
+if (size < 0 || size >= INT_MAX/2)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+ "bad memory allocation requested (%d bytes) at %s %d",
+ size, func, line);
+
if (size < 16) size = 16;
if (!(yield = malloc((size_t)size)))