README.md
1# `cargo fuzz` Targets for Wasmtime
2
3This crate defines various [libFuzzer](https://www.llvm.org/docs/LibFuzzer.html)
4fuzzing targets for Wasmtime, which can be run via [`cargo
5fuzz`](https://rust-fuzz.github.io/book/cargo-fuzz.html).
6
7These fuzz targets just glue together pre-defined test case generators with
8oracles and pass libFuzzer-provided inputs to them. The test case generators and
9oracles themselves are independent from the fuzzing engine that is driving the
10fuzzing process and are defined in `wasmtime/crates/fuzzing`.
11
12## Safety warning
13
14Fuzzers exist to generate random garbage and then try running it. **You
15should not trust these fuzz targets**: they could in theory try to read
16or write files on your disk, send your private data to reporters, or do
17anything else. If they succeed at doing something malicious, they are
18doing a great job at identifying dangerous bugs and we're proud of them.
19
20In addition, some of these fuzz targets use other libraries, such as to
21test that our implementation matches other WebAssembly runtimes. **We
22have not reviewed those runtimes or libraries** for safety, security,
23correctness, supply-chain attacks, or any other properties. Software
24used only during fuzzing is not subject to [our usual `cargo vet`
25requirements][vet-docs].
26
27[vet-docs]: https://docs.wasmtime.dev/contributing-coding-guidelines.html#dependencies-of-wasmtime
28
29Paragraphs 7 and 8 of the license which this work is distributed to you
30under are especially important here: **We disclaim all warranties and
31liability** if running some fuzz target causes you any harm.
32
33Therefore, **if you are at all concerned about the safety of your
34computer**, then you should either not run these fuzz targets, or only
35run them in a sandbox with sufficient isolation for your threat model.
36
37## Example
38
39To start fuzzing run the following command, where `$MY_FUZZ_TARGET` is one of
40the [available fuzz targets](#available-fuzz-targets):
41
42```console
43cargo fuzz run $MY_FUZZ_TARGET
44```
45
46## Available Fuzz Targets
47
48At the time of writing, we have the following fuzz targets:
49
50* `api_calls`: stress the Wasmtime API by executing sequences of API calls; only
51 the subset of the API is currently supported.
52* `compile`: Attempt to compile libFuzzer's raw input bytes with Wasmtime.
53* `compile-maybe-invalid`: Attempt to compile a wasm-smith-generated Wasm module
54 with code sequences that may be invalid.
55* `cranelift-fuzzgen`: Generate a Cranelift function and check that it returns
56 the same results when compiled to the host and when using the Cranelift
57 interpreter; only a subset of Cranelift IR is currently supported.
58* `cranelift-icache`: Generate a Cranelift function A, applies a small mutation
59 to its source, yielding a function A', and checks that A compiled +
60 incremental compilation generates the same machine code as if A' was compiled
61 from scratch.
62* `differential`: Generate a Wasm module, evaluate each exported function
63 with random inputs, and check that Wasmtime returns the same results as a
64 choice of another engine: the Wasm spec interpreter (see the
65 `wasm-spec-interpreter` crate), the `wasmi` interpreter, V8 (through the `v8`
66 crate), or Wasmtime itself run with a different configuration.
67* `instantiate`: Generate a Wasm module and Wasmtime configuration and attempt
68 to compile and instantiate with them.
69* `instantiate-many`: Generate many Wasm modules and attempt to compile and
70 instantiate them concurrently.
71* `spectests`: Pick a random spec test and run it with a generated
72 configuration.
73* `table_ops`: Generate a sequence of `externref` table operations and run them
74 in a GC environment.
75
76The canonical list of fuzz targets is the `.rs` files in the `fuzz_targets`
77directory:
78
79```console
80ls wasmtime/fuzz/fuzz_targets/
81```
82
83## Corpora
84
85While you *can* start from scratch, libFuzzer will work better if it is given a
86[corpus](https://www.llvm.org/docs/LibFuzzer.html#corpus) of seed inputs to kick
87start the fuzzing process. We maintain a corpus for each of these fuzz targets
88in [a dedicated repo on
89github](https://github.com/bytecodealliance/wasmtime-libfuzzer-corpus).
90
91You can use our corpora by cloning it and placing it at `wasmtime/fuzz/corpus`:
92
93```console
94git clone \
95 https://github.com/bytecodealliance/wasmtime-libfuzzer-corpus.git \
96 wasmtime/fuzz/corpus
97```
98
99## Reproducing a Fuzz Bug
100
101When investigating a fuzz bug (especially one found by OSS-Fuzz), use the
102following steps to reproduce it locally:
103
1041. Download the test case (either the "Minimized Testcase" or "Unminimized
105 Testcase" from OSS-Fuzz will do).
1062. Run the test case in the correct fuzz target:
107 ```console
108 cargo +nightly fuzz run $MY_FUZZ_TARGET $MY_TEST_CASE
109 ```
110 If all goes well, the bug should reproduce and libFuzzer will dump the
111 failure stack trace to stdout
1123. For more debugging information, run the command above with `RUST_LOG=debug`
113 to print the configuration and WebAssembly input used by the test case (see
114 uses of `log_wasm` in the `wasmtime-fuzzing` crate).
115
116## Target specific options
117
118### `cranelift-fuzzgen`
119
120Fuzzgen supports passing the `FUZZGEN_ALLOWED_OPS` environment variable, which when available restricts the instructions that it will generate.
121
122Running `FUZZGEN_ALLOWED_OPS=ineg,ishl cargo fuzz run cranelift-fuzzgen` will run fuzzgen but only generate `ineg` or `ishl` opcodes.
123
124### `cranelift-icache`
125
126The icache target also uses the fuzzgen library, thus also supports the `FUZZGEN_ALLOWED_OPS` environment variable as described in the `cranelift-fuzzgen` section above.
127
128