Source code for the WASI fuzzer presented in "WAFL: Binary-Only WebAssembly Fuzzing with Fast Snapshots", based on WAVM and AFL++.
You'll need Clang, CMake, Git and LLD, plus the Zlib and LLVM development libraries.
sudo apt install clang cmake git lld llvm-dev zlib1g-dev
Then, clone this repository including its AFL++ submodule and compile AFL++.
git clone https://github.com/fgsect/WAFL
cd WAFL
git submodule update --init
cd AFLplusplus
make WAFL_MODE=1 TEST_MMAP=1
Next, we'll compile the WAVM part.
mkdir ../build && cd ../build
cmake .. -DCMAKE_BUILD_TYPE=Release
make wavm -j$(nproc)
Done! You can now start fuzzing.
Prior to fuzzing, you need to create an input directory with at least one non-empty file. Then run AFL:
AFL_SKIP_BIN_CHECK=1 ./afl-fuzz -i <INDIR> -o <OUTDIR> ../build/bin/wavm run <WASM FILE>
You may get error messages depending on your OS;
for testing purposes, you can safely override them using
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
and / or AFL_SKIP_CPUFREQ=1
.
Note: Additionally you should always enable snapshots, they increase performance considerably!
Some aspects of WAFL can be controlled using environment variables.
Environment Variable | Options | |
---|---|---|
Snapshot & Reset | __AFL_PERSISTENT |
0 (default) or 1 |
Shared Mem. Input | __AFL_SHM_FUZZ |
0 (default) or 1 |
Allowlist | AFL_LLVM_ALLOWLIST |
Path to allowlist |
Denylist | AFL_LLVM_DENYLIST |
Path to denylist (e.g. wasi-blocklist.txt) |
Instrumentation | AFL_LLVM_INSTRUMENT |
classic , lto , native (default), none |
WAVM provides us with an option to separate compilation (and instrumentation) from execution. This can be useful for large binaries. The Allowlist, Denylist and Instrumentation environment variables shown above can be applied in the pre-compilation step.
../build/bin/wavm compile <WASM FILE> <COMPILED>
Afterwards, fuzz the precompiled binary and turn off instrumentation:
AFL_LLVM_INSTRUMENT=none AFL_SKIP_BIN_CHECK=1 ./afl-fuzz -i <INDIR> -o <OUTDIR> ../build/bin/wavm run --precompiled <COMPILED>
WAVM is available under a 3-Clause BSD license and uses
third-party software under various licenses.
WAFL components based on AFL++ (files in Lib/wavm-afl
and Include/WAVM/wavm-afl
) are licensed under the Apache License 2.0.