Continuation Result Panics Stack-Switching Embeddings
Affected HEAD: 3ebfbe5af4927c157d6fcaca42b8dbb6d17b73fb
Sink: crates/wasmtime/src/runtime/values.rs:331 in Val::_from_raw
Observed verdict: valid continuation return value reaches unimplemented!()
Summary
With WebAssembly stack switching enabled, an untrusted module can panic the host merely by returning a null continuation reference from an exported function. Wasmtime accepts the module and executes the function, but its public call-result conversion has no implementation for continuation heap types and invokes unimplemented!() instead of returning a value or recoverable error.
Detail
After Func::call returns, Wasmtime converts each raw result according to its validated ValType. Val::_from_raw handles function, external, and GC reference families, but routes NoCont, ConcreteCont, and Cont to an unconditional panic:
HeapType::NoCont | HeapType::ConcreteCont(_) | HeapType::Cont => {
unimplemented!()
}
The module needs no continuation operations: returning ref.null cont is enough. The existing wasmtime run --invoke path reaches the same public result conversion used by synchronous embedding calls. No custom harness is needed.
Reproduce
set -eu
git clone --depth 1 https://github.com/bytecodealliance/wasmtime.git
cd wasmtime
git rev-parse HEAD
cargo build --bin wasmtime --no-default-features \
--features 'run,wat,cranelift,compile,stack-switching,clap/default,clap/wrap_help'
cat > cont-result.wat <<'WAT'
(module
(func (export "crash") (result (ref null cont))
(ref.null cont)))
WAT
set +e
RUST_BACKTRACE=0 ./target/debug/wasmtime run -W stack-switching=y \
--invoke crash cont-result.wat
status=$?
set -e
printf 'exit=%s\n' "$status"
Observed output on the affected HEAD:
3ebfbe5af4927c157d6fcaca42b8dbb6d17b73fb
thread 'main' (...) panicked at crates/wasmtime/src/runtime/values.rs:331:25:
not implemented
exit=101
Credit
Zheng Yu @ DepthFirst