I noticed that `TableOp::insert` had assertions that `num_params` and `table_size` were greater than 0, but no assert for `num_globals`. These asserts couldn't be hit because the `*_RANGE` constants were all set to a minimum of 1. But the only reason I can see to prohibit 0-sized tables, locals, or globals, was because indexes into those spaces were generated with the `%` operator. Allowing 0-sized spaces requires not generating the corresponding instructions at all when there are no valid indexes. So I pushed the final selection of which table/local/global to access earlier, to the moment when we're picking which TableOps to run. Then, instead of generating a random u8 or u32 and taking the remainder to get it into the right range, I can just ask `arbitrary` to generate a number in the right range to begin with. So this now explores some size-0 corners that it didn't before, and it doesn't require reasoning about whether remainder can divide by zero. Also I think it uses fewer bits of the `Unstructured` input to produce the same cases, and I hope that lets libFuzzer more quickly find bits it can mutate to get to novel coverage paths.
Fuzzing Infrastructure for Wasmtime
This crate provides test case generators and oracles for use with fuzzing.
These generators and oracles are generally independent of the fuzzing engine
that might be using them and driving the whole fuzzing process (e.g. libFuzzer
or AFL). As such, this crate does not contain any actual fuzz targets
itself. Those are generally just a couple lines of glue code that plug raw input
from (for example) libFuzzer into a generator, and then run one or more
oracles on the generated test case.
If you're looking for the actual fuzz target definitions we currently have, they
live in wasmtime/fuzz/fuzz_targets/* and are driven by cargo fuzz and
libFuzzer.