Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fixed frame allocation from an awaited frame.
njs_function_frame_save() is used to save the awaited frame when "await"
instruction is encountered. The saving was done as a memcpy() of
existing runtime frame.

njs_function_frame_alloc() is used to alloc a new function frame, this
function tries to use a spare preallocated memory from the previous
frame first.  Previously, this function might result in "use-after-free"
when invoked from a restored frame saved with njs_function_frame_save().
Because njs_function_frame_save() left pointers to the spare memory of
the original frame which may be already free when saved frame is
restored.

The fix is to erase fields for the spare memory from the saved frame.

This closes #469 issue on Github.
  • Loading branch information
xeioex committed Feb 21, 2022
1 parent e673ae4 commit ad48705
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/njs_function.c
Expand Up @@ -811,9 +811,13 @@ njs_function_frame_save(njs_vm_t *vm, njs_frame_t *frame, u_char *pc)
njs_native_frame_t *active, *native;

*frame = *vm->active_frame;

frame->previous_active_frame = NULL;

native = &frame->native;
native->size = 0;
native->free = NULL;
native->free_size = 0;

active = &vm->active_frame->native;
value_count = njs_function_frame_value_count(active);
Expand Down
26 changes: 26 additions & 0 deletions test/js/async_recursive_large.t.js
@@ -0,0 +1,26 @@
/*---
includes: [compareArray.js]
flags: [async]
---*/

let stages = [];

async function f(v) {
if (v == 1000) {
return;
}

stages.push(`f>${v}`);

await "X";

await f(v + 1);

stages.push(`f<${v}`);
}

f(0)
.then(v => {
assert.sameValue(stages.length, 2000);
})
.then($DONE, $DONE);
2 changes: 1 addition & 1 deletion test/js/async_recursive_mid.t.js
Expand Up @@ -6,7 +6,7 @@ flags: [async]
let stages = [];

async function f(v) {
if (v == 3) {
if (v == 1000) {
return;
}

Expand Down

0 comments on commit ad48705

Please sign in to comment.