[njs] Fixed heap-use-after-free in JSON.parse().

Alexander Borisov alexander.borisov at nginx.com
Tue Oct 6 16:54:19 UTC 2020


details:   https://hg.nginx.org/njs/rev/119064deed61
branches:  
changeset: 1535:119064deed61
user:      Alexander Borisov <alexander.borisov at nginx.com>
date:      Tue Oct 06 19:53:26 2020 +0300
description:
Fixed heap-use-after-free in JSON.parse().

This correctly fixes the issues addressed in 1405:9beb9ea093b5.
The initial fix wrongly assumed that the "value" pointer is still valid when
njs_is_fast_array(&state->value) is true and the pointer can be used for
the fast path.  This is not the case when the array object is resized.

Moreover, the fast path branch may be completely eliminated because
JSON.parse() with the replacer function is relatively slow by itself.

This closes #323, #324, #325 issues on GitHub.

diffstat:

 src/njs_json.c           |  18 ------------------
 src/test/njs_unit_test.c |   4 ++++
 2 files changed, 4 insertions(+), 18 deletions(-)

diffs (42 lines):

diff -r f6bf6357ab6b -r 119064deed61 src/njs_json.c
--- a/src/njs_json.c	Fri Oct 02 12:18:44 2020 +0000
+++ b/src/njs_json.c	Tue Oct 06 19:53:26 2020 +0300
@@ -1018,24 +1018,6 @@ njs_json_parse_iterator_call(njs_vm_t *v
             return ret;
         }
 
-        /*
-         * The njs_function_apply() function can convert fast array to object.
-         * After this conversion, there will be garbage in the value.
-         */
-
-        if (njs_fast_path(njs_is_fast_array(&state->value)
-            && (state->index - 1) < njs_array(&state->value)->length))
-        {
-            if (njs_is_undefined(&parse->retval)) {
-                njs_set_invalid(value);
-
-            } else {
-                *value = parse->retval;
-            }
-
-            break;
-        }
-
         if (njs_is_undefined(&parse->retval)) {
             ret = njs_value_property_i64_delete(vm, &state->value,
                                                 state->index - 1, NULL);
diff -r f6bf6357ab6b -r 119064deed61 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Fri Oct 02 12:18:44 2020 +0000
+++ b/src/test/njs_unit_test.c	Tue Oct 06 19:53:26 2020 +0300
@@ -16437,6 +16437,10 @@ static njs_unit_test_t  njs_test[] =
                  "                   function(k, v) {return v.a.a;}); o"),
       njs_str("TypeError: cannot get property \"a\" of undefined") },
 
+    { njs_str("function func() {this[8] = 1; return new Int8Array(func)}"
+              "JSON.parse('[1]', func);"),
+      njs_str("") },
+
     /* JSON.stringify() */
 
     { njs_str("JSON.stringify()"),


More information about the nginx-devel mailing list