SECURITY: Refuse negative and large store allocations
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Mon, 29 Mar 2021 21:02:34 +0000 (23:02 +0200)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Tue, 27 Apr 2021 22:40:42 +0000 (00:40 +0200)
Based on Phil Pennock's commits b34d3046 and e6c1606a.  Done by Qualys.

(cherry picked from commit 09d36bd64fc5bf71d8882af35c41ac4e8599acc1)

src/src/store.c

index 305ae6334329b04bad649ddf86fbe03d15dec5a7..123df70eeaf2a7e8d6552aff8b44bc93be5e7e8a 100644 (file)
@@ -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)))