[njs] Fixed heap-use-after-free in JSON.parse() function.
Alexander Borisov
alexander.borisov at nginx.com
Wed May 27 15:19:39 UTC 2020
details: https://hg.nginx.org/njs/rev/9beb9ea093b5
branches:
changeset: 1405:9beb9ea093b5
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Wed May 27 18:18:40 2020 +0300
description:
Fixed heap-use-after-free in JSON.parse() function.
diffstat:
src/njs_json.c | 24 ++++++++++++++++++++++--
src/test/njs_unit_test.c | 17 +++++++++++++++++
2 files changed, 39 insertions(+), 2 deletions(-)
diffs (64 lines):
diff -r 4fb07fcbb698 -r 9beb9ea093b5 src/njs_json.c
--- a/src/njs_json.c Wed May 27 12:02:59 2020 +0000
+++ b/src/njs_json.c Wed May 27 18:18:40 2020 +0300
@@ -1018,11 +1018,31 @@ 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)) {
- njs_set_invalid(value);
+ njs_value_property_i64_delete(vm, &state->value, state->index - 1,
+ NULL);
} else {
- *value = parse->retval;
+ njs_value_property_i64_set(vm, &state->value, state->index - 1,
+ &parse->retval);
}
break;
diff -r 4fb07fcbb698 -r 9beb9ea093b5 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed May 27 12:02:59 2020 +0000
+++ b/src/test/njs_unit_test.c Wed May 27 18:18:40 2020 +0300
@@ -15309,6 +15309,23 @@ static njs_unit_test_t njs_test[] =
"args.join('|')"),
njs_str("0:2|a:3|1:[object Object]|:2,[object Object]") },
+ { njs_str("JSON.parse('[0,1,2]', function(k, v) {"
+ " if (v == 2) {"
+ " return undefined;"
+ " }"
+ " return v;"
+ "});"),
+ njs_str("0,1,") },
+
+ { njs_str("JSON.parse('[0,1,2]', function(k, v) {"
+ " if (v == 0) {"
+ " Object.defineProperty(this, '0', {value: undefined, enumerable: false});"
+ " return undefined;"
+ " }"
+ " return v;"
+ "});"),
+ njs_str(",1,2") },
+
{ njs_str("JSON.parse()"),
njs_str("SyntaxError: Unexpected token at position 0") },
More information about the nginx-devel
mailing list