Skip to content

chore(fuzzing): Improve wasm execution fuzzers#8632

Merged
venkkatesh-sekar merged 18 commits intomasterfrom
vsekar/fuzz_api_type
Feb 9, 2026
Merged

chore(fuzzing): Improve wasm execution fuzzers#8632
venkkatesh-sekar merged 18 commits intomasterfrom
vsekar/fuzz_api_type

Conversation

@venkkatesh-sekar
Copy link
Member

@venkkatesh-sekar venkkatesh-sekar commented Jan 31, 2026

This PR sends some love to the Wasm execution fuzzers, as they were in maintenance mode for some time and haven't caught up with the recent changes in the execution environment.

Production code changes:

  1. Adds a new test method set_api_type to rs/embedders/src/wasmtime_embedder/system_api.rs to hot reload the ApiType for SystemApiImpl. (This affects some constants within the state as well, but I don't think they are necessary for the fuzzer).

execute_with_wasm_executor_afl

  1. In the previous versions, WasmExecutionInput was created for every Wasm method executed, but this was done poorly. The CompilationCache was created fresh for each input, and thus the Wasm was compiled every time a method was executed. The current change utilizes WasmExecutor.create_execution_state to compile and instantiate the Wasm, and we pass the compilation_cache used here to WasmExecutionInput. This improves the fuzzer speed by 10x.
  2. Every time a method was executed, a new ExecutionState was created, including the SystemState. To extend the coverage of the fuzzer, the result of the previous method's execution is persisted for the next method. This includes ExecutionState and SystemState, but the changes carried over are done conservatively. Precisely, this includes globals, wasm_memory, stable_memory, and balance changes in SystemState.
  3. Previously, the ApiType was always set to Init, which was not right. To extend the coverage, we set the correct ApiType for the method, as this influences the system API responses.
  4. The SystemState also contains a dummy call_context, as some system API operations like msg_cycles_accept panic without it (rightfully).

ic_wasm.rs

  1. There was some machinery to extract exported_globals, since the previous version of execute_with_wasm_executor_afl required it. Since this is now done via WasmExecutor.create_execution_state, we can remove generating exported_globals from ICWasmModule.
  2. wasm_smith::Config sets every new Wasm proposal to enabled, which created a lot of invalid Wasm. This is fine from the compiler fuzzer point of view, but the execution fuzzers don't require it. Hence, the struct is exhaustively listed, and the addition of new fields will fail compilation.
  3. The ability to generate 32-bit system API is brought back (lost in some refactoring).

import.rs

The ability to generate 32-bit system API is brought back (lost in some refactoring).

compile.rs

SerializedModuleBytes is not required to be deterministic, and we set it as empty to hold the equality check for other fields.

execute_with_wasmtime_afl

ApiType change as above.

differential...

ApiType change as above.

We had excluded having a Cargo.toml for fuzzers in the hope of a Bazel solution for Rust Analyzer. The day hasn't come after years, so I have added a Cargo.toml for the wasm_fuzzers library, as this improves fixing issues a lot quicker.

@github-actions github-actions bot added the chore label Jan 31, 2026
@venkkatesh-sekar venkkatesh-sekar changed the title chore: Switch ApiType used by WasmExecutor in fuzzing chore: improve WasmExecutor fuzzer Feb 3, 2026
@venkkatesh-sekar venkkatesh-sekar changed the title chore: improve WasmExecutor fuzzer chore(fuzzing): Improve wasm execution fuzzers Feb 5, 2026
@venkkatesh-sekar venkkatesh-sekar self-assigned this Feb 5, 2026
@venkkatesh-sekar venkkatesh-sekar marked this pull request as ready for review February 5, 2026 07:59
@venkkatesh-sekar venkkatesh-sekar requested a review from a team as a code owner February 5, 2026 07:59
@venkkatesh-sekar venkkatesh-sekar added this pull request to the merge queue Feb 9, 2026
Merged via the queue into master with commit 37acf5b Feb 9, 2026
42 checks passed
@venkkatesh-sekar venkkatesh-sekar deleted the vsekar/fuzz_api_type branch February 9, 2026 09:37
kpop-dfinity pushed a commit that referenced this pull request Feb 20, 2026
This PR sends some love to the Wasm execution fuzzers, as they were in
maintenance mode for some time and haven't caught up with the recent
changes in the execution environment.

**Production code changes:**

1. Adds a new test method `set_api_type` to
`rs/embedders/src/wasmtime_embedder/system_api.rs` to hot reload the
`ApiType` for `SystemApiImpl`. (This affects some constants within the
state as well, but I don't think they are necessary for the fuzzer).

### `execute_with_wasm_executor_afl`

1. In the previous versions, `WasmExecutionInput` was created for every
Wasm method executed, but this was done poorly. The `CompilationCache`
was created fresh for each input, and thus the Wasm was compiled every
time a method was executed. The current change utilizes
`WasmExecutor.create_execution_state` to compile and instantiate the
Wasm, and we pass the `compilation_cache` used here to
`WasmExecutionInput`. This improves the fuzzer speed by 10x.
2. Every time a method was executed, a new `ExecutionState` was created,
including the `SystemState`. To extend the coverage of the fuzzer, the
result of the previous method's execution is persisted for the next
method. This includes `ExecutionState` and `SystemState`, but the
changes carried over are done conservatively. Precisely, this includes
globals, `wasm_memory`, `stable_memory`, and balance changes in
`SystemState`.
3. Previously, the `ApiType` was always set to `Init`, which was not
right. To extend the coverage, we set the correct `ApiType` for the
method, as this influences the system API responses.
4. The `SystemState` also contains a dummy `call_context`, as some
system API operations like `msg_cycles_accept` panic without it
(rightfully).

### `ic_wasm.rs`

1. There was some machinery to extract `exported_globals`, since the
previous version of `execute_with_wasm_executor_afl` required it. Since
this is now done via `WasmExecutor.create_execution_state`, we can
remove generating `exported_globals` from `ICWasmModule`.
2. `wasm_smith::Config` sets every new Wasm proposal to enabled, which
created a lot of invalid Wasm. This is fine from the compiler fuzzer
point of view, but the execution fuzzers don't require it. Hence, the
struct is exhaustively listed, and the addition of new fields will fail
compilation.
3. The ability to generate 32-bit system API is brought back (lost in
some refactoring).

### `import.rs`

The ability to generate 32-bit system API is brought back (lost in some
refactoring).

### `compile.rs`

`SerializedModuleBytes` is not required to be deterministic, and we set
it as empty to hold the equality check for other fields.

### `execute_with_wasmtime_afl`

`ApiType` change as above.

### `differential...`

`ApiType` change as above.

We had excluded having a Cargo.toml for fuzzers in the hope of a Bazel
solution for Rust Analyzer. The day hasn't come after years, so I have
added a Cargo.toml for the `wasm_fuzzers` library, as this improves
fixing issues a lot quicker.

---------

Co-authored-by: IDX GitHub Automation <infra+github-automation@dfinity.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants