A Move source code level fuzzer.
# Rebuild is necessary for using your uid
make build-docker
# The run script will run commands in the docker container
./run makeIf you have Rust and cargo installed locally, you can simply run make.
The fuzz targets lives in fuzz/fuzz_targets:
| Target | Oracle | Fuzzing Engine | 
|---|---|---|
v2_only.rs | 
Crash | libFuzzer | 
v1v2.rs | 
Compiler V1 vs. V2 | libFuzzer | 
opt_noopt.rs | 
Optimization On vs. Off | libFuzzer | 
hfuzz_v1v2.rs | 
Compiler V1 vs. V2 | honggfuzz | 
afl_v1v2.rs | 
Compiler V1 vs. V2 | afl++ | 
random.rs | 
Compiler V1 vs. V2 | Pure random input | 
./scripts/fuzz.sh <fuzz_target> [total_hour] [jobs] [max_input_len] [timeout]
# For example
./scripts/fuzz.sh v1v2 24 32 4 3
# This will run the `v1v2` target for 24 hours using 32 cores,
# with randomly created seeds whose size doesn't exceed 4KB.
# For each input, it will timeout after 3 seconds.
# If a fuzz target starts with `afl++`, the script will spawn nodes in a tmux session:
./scripts/fuzz.sh afl-v1v2 24
# This will create a tmux session `afl_fuzzing` where each node occupies a window.The script will keep a copy of log under logs.
Note that the script will automatically spawn tmux sessions for running AFL++
fuzzing sessions so be careful using AFL inside a tmux session.
For libFuzzer, crashing inputs are stored in fuzz/artifacts/<fuzz_target>.
For AFL++, they are stored in fuzz/afl/<fuzz_target>_out/fuzzer#/crashes.
After running a fuzzing session, the coverage of all stored corpus can be generated by:
./scripts/coverage.sh <fuzz_target> [base_dir]If the fuzzing session was run on the local machine, you can ignore base_dir.
If you want to generate the coverage from a different corpus (e.g. generated from another machine),
use the base_dir to specify the directory that contains fuzz/ where corpus is stored for libFuzzer,
or afl is stored for AFL++.
This will create an HTML report at [base_dir/]coverage/<fuzz_target>/index.html.
For libFuzzer results, you can use the scipts/coverage_graph.py to draw a coverage over time graph:
python scripts/coverage_graph.py path/to/logMoveSmith depend on the following crates for fuzzing:
cargo install cargo-fuzz
cargo install cargo-afl
cargo install cargo-binutils
cargo install honggfuzzTo generate human-readable coverage reports, we need llvm coverage tools.
They can be installed with:
cargo install cargo-binutils
rustup component add --toolchain nightly llvm-tools-previewWe also need a demangler installed:
cargo install rustfilt
To run AFL++ targets, you need to install [cargo-afl][cargo-afl]:
cargo install cargo-aflTo plot AFL++ statistics, you might need to install gnuplot:
brew install gnuplotTo view AFL++ coverage over time, you can use
cargo afl plot fuzz/afl/<fuzz_target>_out/fuzzer0 <ouput_dir>to plot several key statistics.
They can be viewed at <output_dir>/index.html.
.
├── enuminto               // Helper crate
├── framework              // The core generation framework
├── fuzz
│   └── fuzz_targets       // All the fuzz targets
├── msmith                 // The Move generators, states, and peripherals
│   └── src
│       ├── cli            // The `msmith` command line tool
│       ├── codegen        // Turn MoveAST to text format Move code
│       ├── execution      // Execution engine using transactional test
│       ├── generators     // Move generators
│       └── states         // Move states
└── scripts                // Helper scripts for running fuzzing and collecting coverage