summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wasm-smith/README.md
blob: 489918aca4078bf0504bc6eff13f2b62b281a1f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# `wasm-smith`

**A WebAssembly test case generator.**

[![](https://docs.rs/wasm-smith/badge.svg)](https://docs.rs/wasm-smith/)
[![](https://img.shields.io/crates/v/wasm-smith.svg)](https://crates.io/crates/wasm-smith)
[![](https://img.shields.io/crates/d/wasm-smith.svg)](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
```