Skip to content

Commit

Permalink
Fix use-after-free on error during module evaluation
Browse files Browse the repository at this point in the history
E.g. if during evaluation of module A, we start loading module B and
an error occurs. This results in a call to js_free_modules() with
JS_FREE_MODULE_NOT_EVALUATED, and since module A isn't yet evaluated,
it gets freed prematurely.

To solve this we improve js_free_modules() to ensure `eval_mark` is not
set. Once js_evaluate_module() returns for module A, it will notice that
an exception occurred and call js_free_modules() with
JS_FREE_MODULE_NOT_EVALUATED. Since `eval_mark` has been cleared by then,
module A gets cleaned up as well.

Co-authored-by: Ole André Vadla Ravnås <[email protected]>
  • Loading branch information
saghul and oleavr authored Nov 7, 2023
1 parent a3a57fe commit 4f02ab8
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2225,7 +2225,8 @@ static void js_free_modules(JSContext *ctx, JSFreeModuleEnum flag)
JSModuleDef *m = list_entry(el, JSModuleDef, link);
if (flag == JS_FREE_MODULE_ALL ||
(flag == JS_FREE_MODULE_NOT_RESOLVED && !m->resolved) ||
(flag == JS_FREE_MODULE_NOT_EVALUATED && !m->evaluated)) {
(flag == JS_FREE_MODULE_NOT_EVALUATED && !m->evaluated
&& !m->eval_mark)) {
js_free_module_def(ctx, m);
}
}
Expand Down Expand Up @@ -28009,6 +28010,7 @@ static JSValue js_evaluate_module(JSContext *ctx, JSModuleDef *m)
ret_val = js_evaluate_module(ctx, m1);
if (JS_IsException(ret_val)) {
m->eval_mark = FALSE;
js_free_modules(ctx, JS_FREE_MODULE_NOT_EVALUATED);
goto clean;
}
if (!JS_IsUndefined(ret_val)) {
Expand Down

0 comments on commit 4f02ab8

Please sign in to comment.