Skip to content

Commit 6b3bed1

Browse files
authored
Fix stack overflow in CVE-2023-31922 (#157)
isArray and proxy isArray can call each other indefinitely in a mutually recursive loop. Add a stack overflow check in the js_proxy_isArray function before calling `JS_isArray(ctx, s->target)`. Original issue: bellard/quickjs#178 CVE: https://nvd.nist.gov/vuln/detail/CVE-2023-31922
1 parent bf1faca commit 6b3bed1

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

quickjs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43612,6 +43612,12 @@ static int js_proxy_isArray(JSContext *ctx, JSValueConst obj)
4361243612
JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY);
4361343613
if (!s)
4361443614
return FALSE;
43615+
43616+
if (js_check_stack_overflow(ctx->rt, 0)) {
43617+
JS_ThrowStackOverflow(ctx);
43618+
return -1;
43619+
}
43620+
4361543621
if (s->is_revoked) {
4361643622
JS_ThrowTypeErrorRevokedProxy(ctx);
4361743623
return -1;

tests/test_builtin.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,25 @@ function test_generator()
707707
assert(v.value === undefined && v.done === true);
708708
}
709709

710+
/* CVE-2023-31922 */
711+
function test_proxy_is_array()
712+
{
713+
for (var r = new Proxy([], {}), y = 0; y < 331072; y++)
714+
r = new Proxy(r, {});
715+
716+
try {
717+
/* Without ASAN */
718+
assert(Array.isArray(r));
719+
} catch(e) {
720+
/* With ASAN expect InternalError "stack overflow" to be raised */
721+
if (e instanceof InternalError) {
722+
assert(e.message, "stack overflow", "Stack overflow error was not raised")
723+
} else {
724+
throw e;
725+
}
726+
}
727+
}
728+
710729
test();
711730
test_function();
712731
test_enum();
@@ -724,3 +743,4 @@ test_map();
724743
test_weak_map();
725744
test_weak_set();
726745
test_generator();
746+
test_proxy_is_array();

0 commit comments

Comments
 (0)