bug: Unexpect exception (memory OOB)
erxiaozhou opened this issue · comments
Summary
An unexpected exception can be triggered on WasmEdge.
Current State
There is an exception indicating "memory OOB".
Expected State
An output: 782761984
Reproduction steps
- Build: ' cmake -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_BUILD_AOT_RUNTIME=OFF .. '
- Execute: 'wasmedge --reactor <case_name> to_test'
Case:
wasmedge_memory_oob.zip - Get error
Screenshots
Any logs you want to share for showing the specific issue
[2024-01-16 02:54:19.844] [error] execution failed: out of bounds memory access, Code: 0x408
[2024-01-16 02:54:19.844] [error] Accessing offset from: 0x00013a06 to: 0x00013a0d , Out of boundary: 0x0000ffff
[2024-01-16 02:54:19.844] [error] In instruction: v128.load8x8_u (0xfd 0x02) , Bytecode offset: 0x0000019c
[2024-01-16 02:54:19.844] [error] When executing function name: "to_test"
Components
CLI
WasmEdge Version or Commit you used
Operating system information
Ubuntu 20.04
Hardware Architecture
x86_64
Compiler flags and options
CMake flags: -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_BUILD_AOT_RUNTIME=OFF
I can reproduce this issue on my machine. Can I get some pointers on how to solve this bug? I am pretty new to this codebase and would love to take on this.
Hi @k3yss
The output shows the error occurs when calling v128.load8x8_u
instruction. So you may need to check the implementation of this and the previous instructions before calling this.
After some debugging I was finally able to pinpoint the below code that was throwing the exception in the file include/runtime/instance/memory.h
/// Check access size is valid.
bool checkAccessBound(uint32_t Offset, uint32_t Length) const noexcept {
const uint64_t AccessLen =
static_cast<uint64_t>(Offset) + static_cast<uint64_t>(Length);
return AccessLen <= MemType.getLimit().getMin() * kPageSize;
}
The value of AccessLen
evalutes to 80398
while the value of MemType.getLimit().getMin() * kPageSize
evalutes to 65536
which causes the expression to become false and in turn throws a memory OOB error.
Two possible solution that comes on top of my head from intuition is:
1: Increase the size of MemType.getLimit().getMin() * kPageSize
. (I am probably wrong here)
2: Somehow decrease the size of AccessLen
. (Probably corrent)
Can I get a review on this approach @hydai.
Both are wrong, the exception point do the right thing, the problem should be why instruction tries to read something out of bound follows above discussion.
This is not a bug in WasmEdge and fixed in Wasmtime (tested in v20.0.2
).
$ ./wasmtime run wasmedge_memory_oob.wasm --invoke to_test
warning: this CLI invocation of Wasmtime will be parsed differently in future
Wasmtime versions -- see this online issue for more information:
https://github.com/bytecodealliance/wasmtime/issues/7384
Wasmtime will now execute with the old (<= Wasmtime 13) CLI parsing,
however this behavior can also be temporarily configured with an
environment variable:
- WASMTIME_NEW_CLI=0 to indicate old semantics are desired and silence this warning, or
- WASMTIME_NEW_CLI=1 to indicate new semantics are desired and use the latest behavior
Error: failed to run main module `wasmedge_memory_oob.wasm`
Caused by:
0: failed to invoke `to_test`
1: error while executing at wasm backtrace:
0: 0x19c - <unknown>!<wasm function 0>
2: memory fault at wasm address 0x13a06 in linear memory of size 0x10000
3: wasm trap: out of bounds memory access
Whish is the same result as WasmEdge:
./wasmedge --reactor wasmedge_memory_oob.wasm to_test
[2024-05-10 12:56:47.758] [error] execution failed: out of bounds memory access, Code: 0x408
[2024-05-10 12:56:47.758] [error] Accessing offset from: 0x00013a06 to: 0x00013a0d , Out of boundary: 0x0000ffff
[2024-05-10 12:56:47.758] [error] In instruction: v128.load8x8_u (0xfa) , Bytecode offset: 0x0000019c
[2024-05-10 12:56:47.758] [error] When executing function name: "to_test"