Skip to content

Commit

Permalink
Fix stack overflow in CVE-2023-31922
Browse files Browse the repository at this point in the history
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).

With ASAN the the poc.js from issue 178:

```
./qjs ./poc.js
InternalError: stack overflow
  at isArray (native)
  at <eval> (./poc.js:4)
```

Fix: bellard/quickjs#178
  • Loading branch information
nickva committed Dec 1, 2023
1 parent a5b9e54 commit 89dd2c2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
6 changes: 6 additions & 0 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -43631,6 +43631,12 @@ static int js_proxy_isArray(JSContext *ctx, JSValueConst obj)
JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY);
if (!s)
return FALSE;

if (js_check_stack_overflow(ctx->rt, 0)) {
JS_ThrowStackOverflow(ctx);
return -1;
}

if (s->is_revoked) {
JS_ThrowTypeErrorRevokedProxy(ctx);
return -1;
Expand Down
20 changes: 20 additions & 0 deletions tests/test_builtin.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,25 @@ function test_generator()
assert(v.value === undefined && v.done === true);
}

/* CVE-2023-31922 */
function test_proxy_is_array()
{
for (var r = new Proxy ([],{}) , y = 0 ; y < 331072 ; y ++ )
r = new Proxy (r, {});

try {
/* Without ASAN */
assert(Array.isArray(r));
} catch(e) {
/* With ASAN expect InternalError "stack overflow" to be raised */
if (e instanceof InternalError) {
assert(e.message, "stack overflow", "Stack overflow error was not raised")
} else {
throw(e);
}
}
}

test();
test_function();
test_enum();
Expand All @@ -724,3 +743,4 @@ test_map();
test_weak_map();
test_weak_set();
test_generator();
test_proxy_is_array();

0 comments on commit 89dd2c2

Please sign in to comment.