Module single_module_fuzzer

Source
Expand description

Support for maintaining the usefulness of a corpus over time.

Wasmtime’s fuzzing strategy in general is to use wasm-smith to generate modules which interprets fuzz input from libFuzzer as a sort of “DNA”. This works to generate pretty interesting modules but falls down over time because the DNA to generate the same module over time can change. This means that maintaining a corpus for Wasmtime is not the most useful thing in the world unfortunately and any historical discoveries of coverage need to be rediscovered every time the DNA changes.

To help with this the module here implements a scheme where Wasmtime’s fuzz inputs are highly likely to be of the form:

[ ... wasm module ... ][ .. fuzz custom section .. ]

The fuzz custom section here contains the original fuzz input used to generate the wasm module, and if the DNA hasn’t changed then it should still be possible to do that as well. The benefit of this format, though, is that if the DNA is changed then the interpretation of the fuzz custom section will change but the original wasm module will not. This enables us to populate the corpus, ideally, with a set of interesting wasm module entries.

Over time the fuzz custom section will “bitrot” and will be no longer able to generate the original wasm module. The main consequence of this is that when the original test case is mutated the generated wasm module from the mutation will be nothing alike from the original test case’s wasm module. This means libFuzzer will have to rediscover ways to mutate into interesting modules, but we’re no worse off than before hopefully. Additionally this more easily opens the door to integrate wasm-mutate one day into mutation here as well.

Currently this is all supported via two methods:

  1. A custom mutator is registered with libfuzzer. This means that all inputs generated by the mutator, so long as they fit, will be the “envelope” format of this module. This means that the corpus will hopefully naturally get populated with wasm files rather than random inputs. Note that this is not guaranteed to succeed since sometimes the buffer to store the fuzz input in the mutator is not big enough to store the final wasm module, in which case a non-enveloped wasm module is stored.

  2. If the environment variable `WRITE_FUZZ_INPUT_TO is set then the fuzz input, in its envelope format, will be written to the specified file. This can be useful in case an input is in its binary form or if a preexisting corpus is being rewritten.

Enums§

KnownValid
Used as part of execute above to determine whether a module is known to be valid ahead of time.

Functions§

execute
Executes a “single module fuzzer” given the raw input from libfuzzer.
mutate
Implementation of a libfuzzer custom mutator for a single-module-fuzzer.