alexcrichton opened issue #11427:
There's a timeout on oss-fuzz right now in the
differentialfuzzer. Debugging this it looks like huge arrays are being allocated in wasm and limits aren't kicking into effect. I've verified that the memory limits aren't being exceeded as all allocations fall under our 1G limit for stores.What appears to be happening is that Cranelift-generated wasm code is taking quite a long time to initialize the array in question. This is under Pulley which is also a slowdown hit too. Differential fuzzing relies on in-wasm fuel counters to ensure execution doesn't take too long and those counters aren't taking into account these "expensive" instructions.
There's a few things I've noticed here and some ideas for solving this:
- Compiled code for
array.new_defaulthas a loop which doesn't contain fuel/epoch checks. That will help in the general case but won't help here because while fuel is enabled for this fuzz test case it's given infinite fuel and relies on in-wasm fuel instead.- Wasm-smith could in theory decrement the size of
array.new_defaultfrom the in-wasm fuel counter before executingarray.new_default, but it doesn't currently.- Host-side allocations of large arrays don't have any await/fuel/epoch checks meaning that large allocations take take a significant chunk of time.
alexcrichton added the fuzz-bug label to Issue #11427.
alexcrichton added the wasm-proposal:gc label to Issue #11427.
alexcrichton commented on issue #11427:
An example of this is:
(type (;18;) (array (mut i8))) ;; ... i32.const 893478245 array.new_default 18Natively this takes 4 seconds to execute, and with a 20x slowdown in fuzzing this easily times out. The hot loop is, in pulley bytecode:
24.16% 28c: xadd64_u32 x0, x1, 893478273 15.26% 293: br_if_xeq64 x2, x0, 0x19 // target = 0x2ac 13.01% 29a: xzero x0 21.63% 29c: xstore8_o32 x2, 0, x0 16.19% 2a3: xadd64_u8 x2, x2, 1 9.74% 2a7: jump -0x1b // target = 0x28cwhich makes sense, this is just a really slow memset.
In differential fuzzing we rely on wasm-smith fuel to limit execution, and wasm-smith's fuel isn't accounting for this loop. Otherwise there's no fuel/epochs happening, which is why this isn't hitting normal timeouts in fuzzing. This is all pulled from https://oss-fuzz.com/testcase-detail/5629900659949568
alexcrichton commented on issue #11427:
cc @fitzgen for if you've got thoughts on this
fitzgen commented on issue #11427:
There's a few things I've noticed here and some ideas for solving this:
* Compiled code for `array.new_default` has a loop which doesn't contain fuel/epoch checks. That will help in the general case but won't help here because while fuel is enabled for this fuzz test case it's given infinite fuel and relies on in-wasm fuel instead. * Wasm-smith could in theory decrement the size of `array.new_default` from the in-wasm fuel counter before executing `array.new_default`, but it doesn't currently. * Host-side allocations of large arrays don't have any await/fuel/epoch checks meaning that large allocations take take a significant chunk of time.I think the answer here is "yes" to all of these. We should also handle
{memory,table}.copysimilarly.
fitzgen edited a comment on issue #11427:
There's a few things I've noticed here and some ideas for solving this:
Compiled code for
array.new_defaulthas a loop which doesn't contain fuel/epoch checks. That will help in the general case but won't help here because while fuel is enabled for this fuzz test case it's given infinite fuel and relies on in-wasm fuel instead.Wasm-smith could in theory decrement the size of
array.new_defaultfrom the in-wasm fuel counter before executingarray.new_default, but it doesn't currently.Host-side allocations of large arrays don't have any await/fuel/epoch checks meaning that large allocations take take a significant chunk of time.
I think the answer here is "yes" to all of these. We should also handle
{memory,table}.copysimilarly.
fitzgen commented on issue #11427:
I think this is fixed by https://github.com/bytecodealliance/wasm-tools/pull/2519 and https://github.com/bytecodealliance/wasmtime/pull/13382 although the former needs to be published and updated here, I can start that process.
fitzgen closed issue #11427:
There's a timeout on oss-fuzz right now in the
differentialfuzzer. Debugging this it looks like huge arrays are being allocated in wasm and limits aren't kicking into effect. I've verified that the memory limits aren't being exceeded as all allocations fall under our 1G limit for stores.What appears to be happening is that Cranelift-generated wasm code is taking quite a long time to initialize the array in question. This is under Pulley which is also a slowdown hit too. Differential fuzzing relies on in-wasm fuel counters to ensure execution doesn't take too long and those counters aren't taking into account these "expensive" instructions.
There's a few things I've noticed here and some ideas for solving this:
- Compiled code for
array.new_defaulthas a loop which doesn't contain fuel/epoch checks. That will help in the general case but won't help here because while fuel is enabled for this fuzz test case it's given infinite fuel and relies on in-wasm fuel instead.- Wasm-smith could in theory decrement the size of
array.new_defaultfrom the in-wasm fuel counter before executingarray.new_default, but it doesn't currently.- Host-side allocations of large arrays don't have any await/fuel/epoch checks meaning that large allocations take take a significant chunk of time.
Last updated: Jun 01 2026 at 09:49 UTC