Skip to content

Commit 145a7e8

Browse files
committed
[forkserver_libafl_cc] Adjust test fuzzer
* Remove 1 second per testcase timeout. The crashes are taking longer and are erroneously treated as a timeout. Under moderate load on my laptop, the crashes were being missed frequently. * Add a max input length parameter akin to AFL++'s afl-fuzz CLI args so that the mutations are more likely to find the objective (crash) * Set the default test to length 10 as the two potential crashes can be found mutating the first 3 or 4 bytes * Relying on grep'ing through the the log of the micro fuzz campaign is inheritly fraught as the printing is infrequent and non-deterministic. Switch to checking the filesystem for results
1 parent a2c0c02 commit 145a7e8

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

fuzzers/forkserver/forkserver_libafl_cc/Justfile

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,25 @@ run: fuzzer
5656
[macos]
5757
test: fuzzer
5858
#!/bin/bash
59-
timeout 30s {{ FORKSERVER }} ./{{ FUZZER_NAME }} ./corpus/ -t 1000 | tee fuzz_stdout.log || true
60-
if grep -qa "objectives: 1" fuzz_stdout.log; then
61-
echo "Fuzzer is working"
59+
CRASH_DIR="crashes"
60+
QUEUE_DIR="corpus_discovered"
61+
timeout 30s {{ FORKSERVER }} -G 10 -t 5000 ./{{ FUZZER_NAME }} ./corpus/ || true
62+
63+
# Print off the crashes/queue for testing before we delete, but don't fail the job
64+
find "${CRASH_DIR}" "${QUEUE_DIR}" -type f -name '[0-9a-f]*' -print -exec od -A x -t x1 -c {} \; 2>/dev/null || true
65+
66+
if find "${CRASH_DIR}" -type f -name '[0-9a-f]*' -printf '.' 2>/dev/null | grep -q .; then
67+
echo "Good, Fuzzer found a crash"
6268
else
63-
echo "Fuzzer does not generate any testcases or any crashes"
69+
echo "Fuzzer did not find a crashing input, and should have"
6470
exit 1
6571
fi
6672

73+
# Cleanup the crashes/queue dirs so that subsequent tests don't pick up
74+
# previous crashes/findings.
75+
# already exited if failed, keep around to debug
76+
rm -r "${CRASH_DIR}" "${QUEUE_DIR}"
77+
6778
[windows]
6879
test: fuzzer
6980
echo "Unsupported on this platform"

fuzzers/forkserver/forkserver_libafl_cc/src/main.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ use std::path::PathBuf;
33

44
use clap::Parser;
55
use libafl::{
6-
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
6+
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
77
events::SimpleEventManager,
8-
executors::{forkserver::ForkserverExecutor, HasObservers, StdChildArgs},
8+
executors::{
9+
forkserver::{ForkserverExecutor, MAX_INPUT_SIZE_DEFAULT},
10+
HasObservers, StdChildArgs,
11+
},
912
feedback_and_fast, feedback_or,
1013
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback},
1114
fuzzer::{Fuzzer, StdFuzzer},
@@ -42,6 +45,14 @@ struct Opt {
4245
)]
4346
executable: String,
4447

48+
#[arg(
49+
help = "set max length of generated fuzz input",
50+
short = 'G',
51+
long = "maxlen",
52+
default_value_t = MAX_INPUT_SIZE_DEFAULT
53+
)]
54+
max_input_len: usize,
55+
4556
#[arg(
4657
help = "The directory to read initial inputs from ('seeds')",
4758
name = "INPUT_DIR",
@@ -53,7 +64,7 @@ struct Opt {
5364
help = "Timeout for each individual execution, in milliseconds",
5465
short = 't',
5566
long = "timeout",
56-
default_value = "1200"
67+
default_value = "3000"
5768
)]
5869
timeout: u64,
5970

@@ -135,8 +146,8 @@ pub fn main() {
135146
let mut state = StdState::new(
136147
// RNG
137148
StdRand::new(),
138-
// Corpus that will be evolved, we keep it in memory for performance
139-
InMemoryCorpus::<BytesInput>::new(),
149+
// Corpus that will be evolved, keep on disk to ensure instrumentation is working
150+
CachedOnDiskCorpus::<BytesInput>::new(PathBuf::from("./corpus_discovered"), 64).unwrap(),
140151
// Corpus in which we store solutions (crashes in this example),
141152
// on disk so the user can get them after stopping the fuzzer
142153
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(),
@@ -180,6 +191,7 @@ pub fn main() {
180191
.parse_afl_cmdline(args)
181192
.coverage_map_size(MAP_SIZE)
182193
.timeout(Duration::from_millis(opt.timeout))
194+
.max_input_size(opt.max_input_len)
183195
.kill_signal(opt.signal)
184196
.build(tuple_list!(time_observer, edges_observer))
185197
.unwrap();

0 commit comments

Comments
 (0)