100 lines
2.7 KiB
Markdown
100 lines
2.7 KiB
Markdown
# `wasm-smith`
|
|
|
|
**A WebAssembly test case generator.**
|
|
|
|
[](https://docs.rs/wasm-smith/)
|
|
[](https://crates.io/crates/wasm-smith)
|
|
[](https://crates.io/crates/wasm-smith)
|
|
|
|
* [Features](#features)
|
|
* [Usage](#usage)
|
|
* [With `cargo fuzz` and `libfuzzer-sys`](#with-cargo-fuzz-and-libfuzzer-sys)
|
|
* [As a Command Line Tool](#as-a-command-line-tool)
|
|
|
|
## Features
|
|
|
|
* **Always valid:** All generated Wasm modules pass validation. `wasm-smith`
|
|
gets past your wasm parser and validator, exercising the guts of your Wasm
|
|
compiler, runtime, or tool.
|
|
|
|
* **Supports the full WebAssembly language:** Doesn't have blind spots or
|
|
unimplemented instructions.
|
|
|
|
* **Implements the
|
|
[`Arbitrary`](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html)
|
|
trait**: Easy to use with [`cargo
|
|
fuzz`](https://github.com/rust-fuzz/cargo-fuzz) and
|
|
[`libfuzzer-sys`](https://github.com/rust-fuzz/libfuzzer)!
|
|
|
|
* **Deterministic:** Given the same input seed, always generates the same output
|
|
Wasm module, so you can always reproduce test failures.
|
|
|
|
* **Plays nice with mutation-based fuzzers:** Small changes to the input tend to
|
|
produce small changes to the output Wasm module. Larger inputs tend to
|
|
generate larger Wasm modules.
|
|
|
|
## Usage
|
|
|
|
### With `cargo fuzz` and `libfuzzer-sys`
|
|
|
|
First, use `cargo fuzz` to define a new fuzz target:
|
|
|
|
```shell
|
|
$ cargo fuzz add my_wasm_smith_fuzz_target
|
|
```
|
|
|
|
Next, add `wasm-smith` to your dependencies:
|
|
|
|
```shell
|
|
$ cargo add wasm-smith
|
|
```
|
|
|
|
Then, define your fuzz target so that it takes arbitrary `wasm_smith::Module`s
|
|
as an argument, convert the module into serialized Wasm bytes via the `to_bytes`
|
|
method, and then feed it into your system:
|
|
|
|
```rust
|
|
// fuzz/fuzz_targets/my_wasm_smith_fuzz_target.rs
|
|
|
|
#![no_main]
|
|
|
|
use libfuzzer_sys::fuzz_target;
|
|
use wasm_smith::Module;
|
|
|
|
fuzz_target!(|module: Module| {
|
|
let wasm_bytes = module.to_bytes();
|
|
|
|
// Your code here...
|
|
});
|
|
```
|
|
|
|
Finally, start fuzzing:
|
|
|
|
```shell
|
|
$ cargo fuzz run my_wasm_smith_fuzz_target
|
|
```
|
|
|
|
> **Note:** Also check out [the `validate` fuzz
|
|
> target](https://github.com/bytecodealliance/wasm-tools/blob/main/fuzz/src/validate.rs)
|
|
> defined in this repository. Using the `wasmparser` crate, it checks that every
|
|
> module generated by `wasm-smith` validates successfully.
|
|
|
|
### As a Command Line Tool
|
|
|
|
Install the CLI tool via `cargo`:
|
|
|
|
```shell
|
|
$ cargo install wasm-tools
|
|
```
|
|
|
|
Convert some arbitrary input into a valid Wasm module:
|
|
|
|
```shell
|
|
$ head -c 100 /dev/urandom | wasm-tools smith -o test.wasm
|
|
```
|
|
|
|
Finally, run your tool on the generated Wasm module:
|
|
|
|
```shell
|
|
$ my-wasm-tool test.wasm
|
|
```
|