luxinyi0105 added the bug label to Issue #6768.
luxinyi0105 opened issue #6768:
Test Case
Steps to Reproduce
...
Expected Results
$ wasmtime run testcase_1.wasm checksum = DAFC642C
Actual Results
$ wasmtime run testcase_1.wasm
Actually, wasmtime outputs nothing.
Versions and Environment
Wasmtime version or commit: wasmtime-cli 12.0.0
Operating system: Ubuntu 22.04.1
Architecture: x86_64
Extra Info
Actually, I don't know what the correct result of the test case should look like, either.
So I used some other WebAssembly runtimes, such as wasmedge and wasm-micro-runtime(WAMR), to execute the same test case, they output the correct checksum result.testcase_2.wasm in zip has the same problem, only for reference.
alexcrichton commented on issue #6768:
Would you be able to provide sources for where the wasm files came from? Other issues in the past (https://github.com/bytecodealliance/wasmtime/issues/6695) have shown that the original source program contains undefined behavior which causes WebAssembly runtimes that don't follow spec-semantics precisely to exhibit different behaviors than Wasmtime. The original sources here could help assist in debugging this.
Can you also clarify what you mean that
testcase_2.wasm
has the same problem? If I run that it printschecksum = 17DAA781
which seems like it may be the expected behavior? If you run it locally does it print nothing?One thing I'm noticing is that it looks like this module is compiled by the Emscripten toolchain. It may be the case that the other runtimes you're testing have some sort of integration to run Emscripten modules or the module is expected to be executed in a particular way. Wasmtime does not implement this (if it exists, I'm not sure if this is happening), which may factor in here.
luxinyi0105 commented on issue #6768:
Would you be able to provide sources for where the wasm files came from? Other issues in the past (#6695) have shown that the original source program contains undefined behavior which causes WebAssembly runtimes that don't follow spec-semantics precisely to exhibit different behaviors than Wasmtime. The original sources here could help assist in debugging this.
Can you also clarify what you mean that
testcase_2.wasm
has the same problem? If I run that it printschecksum = 17DAA781
which seems like it may be the expected behavior? If you run it locally does it print nothing?One thing I'm noticing is that it looks like this module is compiled by the Emscripten toolchain. It may be the case that the other runtimes you're testing have some sort of integration to run Emscripten modules or the module is expected to be executed in a particular way. Wasmtime does not implement this (if it exists, I'm not sure if this is happening), which may factor in here.
Thanks for your reply.
Actually, the original test case was simply mutated a wasm file, which was obtained by compiling the C program generated with Csmith using the Emscripten compiler (Emcc). You can convert wasm file to wat format with wabt and find the mutation operation in line 9974(replace "i32.sub" with "i32.div_s"). Releated files is here.
Note that the process of compiling c files with Emscripten uses -O0 optimization option in order to prevent the introduction of problems releated with compiler optimization. Given the execution results of wasmedge and WAMR, I think that the result of Wasmtime should either output the correct checksum or trigger internal exception handling logic to output runtime errors, rather than the current situation where there is nothing.
As for
testcase_2.wasm
, I tried again in my local environment. The "original" wasm file indeed print nothing, but when I renamed the file to submit it, the renamed file output the correct checksum. Here is the "original" wasm file, and why this problem occurs is not very clear yet.
alexcrichton commented on issue #6768:
Ok thanks for the more information. The mutation there is changing a subtraction of the stack pointer into a division of the stack pointer which means that the wasm module's in-memory shadow-stack pointer is getting corrupted. Notably what this causes is the stack to get misaligned.
Looking at the output more closely, you can see this with
RUST_LOG=trace wasmtime run mutated.wasm
and you'll see:... TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > wiggle abi; module="wasi_snapshot_preview1" function="fd_write" TRACE tracing::span::active > -> wiggle abi; TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > fd=Fd(1) iovs=*guest 0x7fd/2 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > result=Err(Error { inner: Inval }) ...
Here you can see that
fd_write
(the "print to screen" function) is returningInval
which isEINVAL
in the guest. The reason for this is that the guest pointer, 0x7fd, is not aligned to a 4-byte boundary. My guess is that this is being called withprintf
with a buffer from the stack and the mutation which cause the stack to get misaligned is threading through to here.Wasmtime's
wasi_snapshot_preview1
implementation enforces alignment which I would assume the other runtimes you're testing are not enforcing. Alignment for all types is documented but what to do with misaligned values is a bit of an edge case I think today in the sense that I'm at least not myself aware of a strict requirement on what to do. The component model, which WASI is now being defined with, strictly indicates what to do with alignment, but for preview1 it's at least less clear to me.@sunfishcode or @pchickey I'm curious, but have y'all had discussions in the WASI subgroup about this? This is only an issue for preview1 at this point due to the component model otherwise saying what to do. I'm also not sure if this is already documented elsewhere as "alignment must be respected" or not in preview1
pchickey commented on issue #6768:
witx spec says
misaligned pointers ... shall trap
https://github.com/WebAssembly/wasi/blob/main/legacy/tools/witx-docs.md#pointers
alexcrichton commented on issue #6768:
Ah nice thanks! In that case looks like Wasmtime itself also needs to be updated to return a trap in this situation rather than an error code to the guest.
Otherwise though @luxinyi0105 I believe this is all expected behavior from Wasmtime, and if you're interested you may wish to open issues on other wasm runtimes to indicate that they may also not be compliant with the preview1 spec.
luxinyi0105 commented on issue #6768:
Ah nice thanks! In that case looks like Wasmtime itself also needs to be updated to return a trap in this situation rather than an error code to the guest.
Otherwise though @luxinyi0105 I believe this is all expected behavior from Wasmtime, and if you're interested you may wish to open issues on other wasm runtimes to indicate that they may also not be compliant with the preview1 spec.
Fine. Thanks for your suggestion.
alexcrichton commented on issue #6768:
I believe our end is now resolved with https://github.com/bytecodealliance/wasmtime/pull/6776
alexcrichton closed issue #6768:
Test Case
Steps to Reproduce
...
Expected Results
$ wasmtime run testcase_1.wasm checksum = DAFC642C
Actual Results
$ wasmtime run testcase_1.wasm
Actually, wasmtime outputs nothing.
Versions and Environment
Wasmtime version or commit: wasmtime-cli 12.0.0
Operating system: Ubuntu 22.04.1
Architecture: x86_64
Extra Info
Actually, I don't know what the correct result of the test case should look like, either.
So I used some other WebAssembly runtimes, such as wasmedge and wasm-micro-runtime(WAMR), to execute the same test case, they output the correct checksum result.testcase_2.wasm in zip has the same problem, only for reference.
Last updated: Nov 22 2024 at 16:03 UTC