fuzz: Shuffle files before testing them

When iterating over all fuzz input files in a folder, the order should
not matter.

However, shuffling may be useful to detect non-determinism.

Thus, shuffle in fuzz.cpp, when using neither libFuzzer, nor AFL.

Also, shuffle in the deterministic-fuzz-coverage tool, when using
libFuzzer.
This commit is contained in:
MarcoFalke 2025-04-07 12:01:25 +02:00
parent 639279e86a
commit faf2e238fb
No known key found for this signature in database
2 changed files with 10 additions and 3 deletions

View file

@ -133,7 +133,7 @@ fn deterministic_coverage(
let output = { let output = {
let mut cmd = Command::new(fuzz_exe); let mut cmd = Command::new(fuzz_exe);
if using_libfuzzer { if using_libfuzzer {
cmd.arg("-runs=1"); cmd.args(["-runs=1", "-shuffle=1", "-prefer_small=0"]);
} }
cmd cmd
} }

View file

@ -15,6 +15,7 @@
#include <util/sock.h> #include <util/sock.h>
#include <util/time.h> #include <util/time.h>
#include <algorithm>
#include <csignal> #include <csignal>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@ -26,6 +27,7 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <memory> #include <memory>
#include <random>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
@ -241,10 +243,15 @@ int main(int argc, char** argv)
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
fs::path input_path(*(argv + i)); fs::path input_path(*(argv + i));
if (fs::is_directory(input_path)) { if (fs::is_directory(input_path)) {
std::vector<fs::path> files;
for (fs::directory_iterator it(input_path); it != fs::directory_iterator(); ++it) { for (fs::directory_iterator it(input_path); it != fs::directory_iterator(); ++it) {
if (!fs::is_regular_file(it->path())) continue; if (!fs::is_regular_file(it->path())) continue;
g_input_path = it->path(); files.emplace_back(it->path());
Assert(read_file(it->path(), buffer)); }
std::ranges::shuffle(files, std::mt19937{std::random_device{}()});
for (const auto& input_path : files) {
g_input_path = input_path;
Assert(read_file(input_path, buffer));
test_one_input(buffer); test_one_input(buffer);
++tested; ++tested;
buffer.clear(); buffer.clear();