Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ struct ContinuationStore {

// Set when we are resuming execution, that is, re-winding the stack.
bool resuming = false;

// On traps or other errors that unwind the stack, we reset the continuation
// store to return to a clean state ahead of further calls to exports.
void clear() {
continuations.clear();
resuming = false;
}
};

// Execute an expression
Expand Down Expand Up @@ -537,7 +544,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
#if WASM_INTERPRETER_DEBUG
std::cout << indent() << "clear continuations\n";
#endif
continuationStore = std::make_shared<ContinuationStore>();
continuationStore->clear();
}
}

Expand Down
26 changes: 26 additions & 0 deletions test/lit/exec/continuation-leak.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
;; RUN: wasm-opt %s -all --fuzz-exec-before --fuzz-exec-second=%s.second -q -o /dev/null 2>&1 | filecheck %s

;; Check that clearing the continuation store in linked modules clears it in-place,
;; so that continuations leaked from the primary module do not affect the second module.

(module
(type $func_t (func))
(type $cont_t (cont $func_t))
(tag $tag)

(func $f_suspend
(suspend $tag)
)

(func $test1 (export "test1")
(local $c (ref $cont_t))
(local.set $c (cont.new $cont_t (ref.func $f_suspend)))
(resume $cont_t (local.get $c))
)
)

;; CHECK: [fuzz-exec] export test1
;; CHECK-NEXT: [exception thrown: unhandled suspend]
;; CHECK: [fuzz-exec] running second module
;; CHECK-NEXT: [fuzz-exec] export test2
;; CHECK-NEXT: [exception thrown: unhandled suspend]
7 changes: 7 additions & 0 deletions test/lit/exec/continuation-leak.wast.second
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(module
(tag $tag)

(func $test2 (export "test2")
(suspend $tag)
)
)
Loading