-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingfuzz-bugBugs found by a fuzzerBugs found by a fuzzer
Description
Description
When running with cranelift_opt_level(OptLevel::None), Wasmtime returns a different value than the WebAssembly spec and other engines for i32.shr_u where the shift amount is 32. In this mode, Wasmtime yields the same result as if the shift amount were taken verbatim, rather than masked to 5 bits.
This bug was found during differential fuzzing of wasmi 1.0.7 against wasmtime 40.0.1 using ziggy (which uses AFL++ and honggfuzz under the hood) instead of libfuzzer.
Expected behavior
The provided example should execute in the same way with wasmi and wasmtime.
Instead we get:
wasmi says Ok(25), but wasmtime says Ok(1)
Cargo.toml
[package]
name = "reproducing_the_bug"
version = "0.1.0"
edition = "2024"
[dependencies]
wasmi = "1.0.7"
wasmtime = "40.0.1"
wat = "1.228.0"src/main.rs
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wat = r#"
(module
(func (export "") (result i32)
i32.const 24
i32.const 32
i32.shr_u
i32.const 1
i32.const 0
i32.shl
i32.or)
)
"#;
let wasm = wat::parse_str(wat)?;
let wasmi_config = wasmi::Config::default();
let wasmi_engine = wasmi::Engine::new(&wasmi_config);
let wasmi_module = wasmi::Module::new(&wasmi_engine, &wasm)?;
let mut wasmtime_config = wasmtime::Config::new();
wasmtime_config.cranelift_opt_level(wasmtime::OptLevel::None);
let wasmtime_engine = wasmtime::Engine::new(&wasmtime_config)?;
let wasmtime_module = wasmtime::Module::new(&wasmtime_engine, &wasm)?;
let mut wasmi_store = wasmi::Store::new(&wasmi_engine, ());
let wasmi_instance = wasmi::Instance::new(&mut wasmi_store, &wasmi_module, &[])?;
let mut wasmtime_store = wasmtime::Store::new(&wasmtime_engine, ());
let wasmtime_instance = wasmtime::Instance::new(&mut wasmtime_store, &wasmtime_module, &[])?;
let wasmi_func = wasmi_instance.get_typed_func::<(), i32>(&wasmi_store, "")?;
let wasmtime_func = wasmtime_instance.get_typed_func::<(), i32>(&mut wasmtime_store, "")?;
let args = ();
println!(
"wasmi says {:?}, but wasmtime says {:?}",
wasmi_func.call(&mut wasmi_store, args),
wasmtime_func.call(&mut wasmtime_store, args),
);
Ok(())
}This example was also tested against wasmer, which agrees with wasmi (result is 25).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingfuzz-bugBugs found by a fuzzerBugs found by a fuzzer