WasmEdge / WasmEdge

WasmEdge is a lightweight, high-performance, and extensible WebAssembly runtime for cloud native, edge, and decentralized applications. It powers serverless apps, embedded functions, microservices, smart contracts, and IoT devices.
https://WasmEdge.org
Apache License 2.0
8.36k stars 755 forks source link

fuzz: Do not terminate while executing the given testcase #2733

Open luxinyi0105 opened 1 year ago

luxinyi0105 commented 1 year ago

Description

While executing the given testcase, WasmEdge hangs out and does not end.

Current State

$ wasmedge mutated_file_28840.wasm 

It will hang out and does not end.

Expected

I tried to use some other wasm runtimes, such as wasmer, wasmtime, and wasmi, to execute the same testcase.

Wasmer will terminate abnormally due to "misaligned pointer", while wasmtime and wasmi are running normally but will not output anything.

Due to a lack of understanding of WebAssembly, I am unable to determine what the expected result is, maybe one of the two above.

Environment

Extra info

Drawing from the experience of #2710 and #2724, I not only used the default interpreter mode to execute the given testcase, but also used the ahead-of-time mode. By the time I submitted this issue, it had been running for about two hours with AOT mode, but it still did not terminate.

Perhaps there is a problem with my method of using AOT mode, and the details still need you to confirm. Thanks a lot!

image

alabulei1 commented 1 year ago

@hydai Could you please take a look?

vrnimje commented 1 year ago

So I have recreated the results with wasmedge and wasmtime (exits with code 71)

$ RUST_LOG=wasi_common=trace wasmtime mutated_file_28840.wasm 
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > wiggle abi; module="wasi_snapshot_preview1" function="args_sizes_get"
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > result=Ok((1, 24))
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > wiggle abi; module="wasi_snapshot_preview1" function="args_get"
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > argv=*guest 0x10009 argv_buf=*guest 0x10032
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > result=Err(Error { inner: Inval })
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > wiggle abi; module="wasi_snapshot_preview1" function="proc_exit"
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > rval=71
 TRACE wasi_common::snapshots::preview_1::wasi_snapshot_preview1 > result=Exited with i32 exit status 71
$ time ~/WasmEdge/build/tools/wasmedge/wasmedge mutated_file_28840.wasm 
^C
real    0m35.818s
user    0m35.793s
sys 0m0.020s

The case is same even in AOT mode

$ time ~/WasmEdge/build/tools/wasmedge/wasmedge compile mutated_file_28840.wasm mutated.aot.wasm 
[2023-08-27 22:59:26.211] [info] compile start
[2023-08-27 22:59:26.264] [info] verify start
[2023-08-27 22:59:26.276] [info] optimize start
[2023-08-27 22:59:26.664] [info] codegen start
[2023-08-27 22:59:26.954] [info] output start
[2023-08-27 22:59:26.966] [info] compile done
[2023-08-27 22:59:26.968] [info] output start

real    0m0.817s
user    0m0.599s
sys 0m0.044s

$ time ~/WasmEdge/build/tools/wasmedge/wasmedge mutated.aot.wasm
^C
real    0m6.960s
user    0m6.900s
sys 0m0.040s

But I came across something weird, when converting these mutated .wasm files to .wat. When I converted the .wat file back to .wasm, it now shows a out of bounds error...

$ wasm2wat mutated.aot.wasm -o mutated.aot.wat
$ wat2wasm mutated.aot.wat -o mutated1.wasm
$ time ~/WasmEdge/build/tools/wasmedge/wasmedge mutated1.wasm 
[2023-08-27 23:00:45.404] [error] execution failed: out of bounds memory access, Code: 0x88
[2023-08-27 23:00:45.404] [error]     Accessing offset from: 0x09000000 to: 0x09000000 , Out of boundary: 0x00ffffff
[2023-08-27 23:00:45.404] [error]     In instruction: i32.load8_u (0x2d) , Bytecode offset: 0x00011df5
[2023-08-27 23:00:45.404] [error]     When executing function name: "_start"

real    0m0.041s
user    0m0.029s
sys 0m0.012s

As far I could tell, both the .wasm files (mutated.aot.wasm & mutated1.wasm), when converted to .wat, are identical. If someone could look into this, or point out where I went wrong, it would be appreciated.

luxinyi0105 commented 12 months ago

As far I could tell, both the .wasm files (mutated.aot.wasm & mutated1.wasm), when converted to .wat, are identical. If someone could look into this, or point out where I went wrong, it would be appreciated.

Thanks for your reply. According to what you mentioned before, I use wabt to convert between wasm and wat format, and find an interesting phenomenon.

While using wat2wasm to convert mutated.aot.wat to its wasm format, I choose mutated.wasm as the file name of the output wasm file. The result of mutated.wasm running with wasmedge is still "hang out", the same with testcase I submitted before.

Alternatively, you can rename obtained mutated1.wasm to mutated.wasm, and use wasmedge to execute, which has the same effect.

09-08 The situation is interesting, and I'm not sure why it happened. If you or someone else have any new discoveries, we can discuss together. Thanks a lot!