[njs] Fixed size uint32_t overflow in njs_array_expand().

Dmitry Volyntsev xeioex at nginx.com
Thu Nov 22 14:39:04 UTC 2018


details:   https://hg.nginx.org/njs/rev/3b2689be3a57
branches:  
changeset: 664:3b2689be3a57
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu Nov 22 17:38:25 2018 +0300
description:
Fixed size uint32_t overflow in njs_array_expand().

diffstat:

 njs/njs_array.c          |  21 ++++++++++++++++-----
 njs/test/njs_unit_test.c |   6 ++++++
 nxt/nxt_mem_cache_pool.c |   3 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

diffs (108 lines):

diff -r 987f7998a967 -r 3b2689be3a57 njs/njs_array.c
--- a/njs/njs_array.c	Thu Nov 22 15:35:25 2018 +0300
+++ b/njs/njs_array.c	Thu Nov 22 17:38:25 2018 +0300
@@ -6,6 +6,7 @@
 
 #include <njs_core.h>
 #include <string.h>
+#include <stdint.h>
 
 
 typedef struct {
@@ -136,7 +137,7 @@ njs_array_alloc(njs_vm_t *vm, uint32_t l
 
     size = (uint64_t) length + spare;
 
-    if (nxt_slow_path((size * sizeof(njs_value_t)) >= 0xffffffff)) {
+    if (nxt_slow_path((size * sizeof(njs_value_t)) >= UINT32_MAX)) {
         goto memory_error;
     }
 
@@ -201,11 +202,12 @@ njs_array_string_add(njs_vm_t *vm, njs_a
 
 njs_ret_t
 njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend,
-    uint32_t size)
+    uint32_t new_size)
 {
+    uint64_t     size;
     njs_value_t  *start, *old;
 
-    size += array->length;
+    size = (uint64_t) new_size + array->length;
 
     if (nxt_fast_path(size <= array->size && prepend == 0)) {
         return NXT_OK;
@@ -218,11 +220,14 @@ njs_array_expand(njs_vm_t *vm, njs_array
         size += size / 2;
     }
 
+    if (nxt_slow_path(((prepend + size) * sizeof(njs_value_t)) >= UINT32_MAX)) {
+        goto memory_error;
+    }
+
     start = nxt_mem_cache_align(vm->mem_cache_pool, sizeof(njs_value_t),
                                 (prepend + size) * sizeof(njs_value_t));
     if (nxt_slow_path(start == NULL)) {
-        njs_memory_error(vm);
-        return NXT_ERROR;
+        goto memory_error;
     }
 
     array->size = size;
@@ -238,6 +243,12 @@ njs_array_expand(njs_vm_t *vm, njs_array
     nxt_mem_cache_free(vm->mem_cache_pool, old);
 
     return NXT_OK;
+
+memory_error:
+
+    njs_memory_error(vm);
+
+    return NXT_ERROR;
 }
 
 
diff -r 987f7998a967 -r 3b2689be3a57 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Thu Nov 22 15:35:25 2018 +0300
+++ b/njs/test/njs_unit_test.c	Thu Nov 22 17:38:25 2018 +0300
@@ -2905,6 +2905,9 @@ static njs_unit_test_t  njs_test[] =
       nxt_string("0:0,1:1,2:2,null:null,undefined:defined,false:false,"
                  "true:true,Infinity:Infinity,-Infinity:-Infinity,NaN:NaN,") },
 
+    { nxt_string("--[][3e9]"),
+      nxt_string("MemoryError") },
+
     { nxt_string("[].length"),
       nxt_string("0") },
 
@@ -2933,6 +2936,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("[].length = 2**32 - 1"),
       nxt_string("MemoryError") },
 
+    { nxt_string("[].length = 3e9"),
+      nxt_string("MemoryError") },
+
     { nxt_string("Object.defineProperty([], 'length',{value: 2**32 - 1})"),
       nxt_string("MemoryError") },
 
diff -r 987f7998a967 -r 3b2689be3a57 nxt/nxt_mem_cache_pool.c
--- a/nxt/nxt_mem_cache_pool.c	Thu Nov 22 15:35:25 2018 +0300
+++ b/nxt/nxt_mem_cache_pool.c	Thu Nov 22 17:38:25 2018 +0300
@@ -14,6 +14,7 @@
 #include <nxt_rbtree.h>
 #include <nxt_mem_cache_pool.h>
 #include <string.h>
+#include <stdint.h>
 
 
 /*
@@ -586,7 +587,7 @@ nxt_mem_cache_alloc_large(nxt_mem_cache_
     nxt_mem_cache_block_t  *block;
 
     /* Allocation must be less than 4G. */
-    if (nxt_slow_path(size >= 0xffffffff)) {
+    if (nxt_slow_path(size >= UINT32_MAX)) {
         return NULL;
     }
 


More information about the nginx-devel mailing list