Skip to content

Commit d334860

Browse files
author
Aarnav
authored
Feature: libafl-fuzzfuzzbench (#2689)
* fuzzbench * clippy * fmt * fix unicorn CI?
1 parent 7938acc commit d334860

5 files changed

Lines changed: 128 additions & 41 deletions

File tree

fuzzers/forkserver/libafl-fuzz/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ libafl_nyx = { path = "../../../libafl_nyx" }
3636
[features]
3737
default = ["track_hit_feedbacks"]
3838
track_hit_feedbacks = ["libafl/track_hit_feedbacks"]
39+
fuzzbench = []

fuzzers/forkserver/libafl-fuzz/Makefile.toml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ script = "echo done"
6565
dependencies = [
6666
"build_afl",
6767
"test_instr",
68+
"test_instr_fuzzbench",
6869
"test_cmplog",
6970
"test_frida",
7071
"test_qemu",
@@ -75,6 +76,10 @@ dependencies = [
7576
script_runner = "@shell"
7677
script = "cargo build --profile ${PROFILE}"
7778

79+
[tasks.build_libafl_fuzz_fuzzbench]
80+
script_runner = "@shell"
81+
script = "cargo build --profile ${PROFILE} --features fuzzbench"
82+
7883
[tasks.test_instr]
7984
script_runner = "@shell"
8085
script = '''
@@ -108,6 +113,39 @@ test -d "./test/output/fuzzer_main/crashes" || {
108113
'''
109114
dependencies = ["build_afl", "build_libafl_fuzz"]
110115

116+
[tasks.test_instr_fuzzbench]
117+
script_runner = "@shell"
118+
script = '''
119+
AFL_PATH=${AFL_DIR} ${AFL_CC_PATH} ./test/test-instr.c -o ./test/out-instr
120+
121+
export LIBAFL_DEBUG_OUTPUT=1
122+
export AFL_CORES=0
123+
export AFL_STATS_INTERVAL=1
124+
125+
timeout 5 ${FUZZER} -i ./test/seeds -o ./test/output-fuzzbench ./test/out-instr || true
126+
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
127+
echo "No new corpus entries found"
128+
exit 1
129+
}
130+
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/fuzzer_stats 2>/dev/null )" || {
131+
echo "No fuzzer_stats file found"
132+
exit 1
133+
}
134+
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/plot_data 2>/dev/null )" || {
135+
echo "No plot_data found"
136+
exit 1
137+
}
138+
test -d "./test/output-fuzzbench/fuzzer_main/hangs" || {
139+
echo "No hangs directory found"
140+
exit 1
141+
}
142+
test -d "./test/output-fuzzbench/fuzzer_main/crashes" || {
143+
echo "No crashes directory found"
144+
exit 1
145+
}
146+
'''
147+
dependencies = ["build_afl", "build_libafl_fuzz_fuzzbench"]
148+
111149
[tasks.test_cmplog]
112150
script_runner = "@shell"
113151
script = '''

fuzzers/forkserver/libafl-fuzz/src/corpus.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{
22
borrow::Cow,
33
fs::File,
4-
io::{self, BufRead, BufReader},
4+
io,
5+
io::{BufRead, BufReader},
56
path::Path,
67
};
78

@@ -164,6 +165,7 @@ pub fn create_dir_if_not_exists(path: &Path) -> io::Result<()> {
164165
}
165166
}
166167

168+
#[cfg(not(feature = "fuzzbench"))]
167169
pub fn remove_main_node_file(output_dir: &Path) -> Result<(), Error> {
168170
for entry in std::fs::read_dir(output_dir)?.filter_map(Result::ok) {
169171
let path = entry.path();

fuzzers/forkserver/libafl-fuzz/src/fuzzer.rs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ use std::{
77
time::Duration,
88
};
99

10+
#[cfg(feature = "fuzzbench")]
11+
use libafl::events::SimpleEventManager;
12+
#[cfg(not(feature = "fuzzbench"))]
13+
use libafl::events::{CentralizedEventManager, LlmpRestartingEventManager};
14+
#[cfg(feature = "fuzzbench")]
15+
use libafl::monitors::SimpleMonitor;
1016
use libafl::{
1117
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
12-
events::{
13-
CentralizedEventManager, EventManagerHooksTuple, LlmpRestartingEventManager,
14-
ProgressReporter,
15-
},
18+
events::ProgressReporter,
1619
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder},
1720
feedback_and, feedback_or, feedback_or_fast,
1821
feedbacks::{
@@ -39,6 +42,8 @@ use libafl::{
3942
},
4043
Error, Fuzzer, HasFeedback, HasMetadata, SerdeAny,
4144
};
45+
#[cfg(not(feature = "fuzzbench"))]
46+
use libafl_bolts::shmem::StdShMemProvider;
4247
use libafl_bolts::{
4348
core_affinity::CoreId,
4449
current_nanos, current_time,
@@ -70,23 +75,47 @@ use crate::{
7075
pub type LibaflFuzzState =
7176
StdState<BytesInput, CachedOnDiskCorpus<BytesInput>, StdRand, OnDiskCorpus<BytesInput>>;
7277

73-
pub fn run_client<EMH, SP>(
74-
state: Option<LibaflFuzzState>,
75-
mut restarting_mgr: CentralizedEventManager<
76-
LlmpRestartingEventManager<(), LibaflFuzzState, SP>,
77-
EMH,
78-
LibaflFuzzState,
79-
SP,
80-
>,
81-
fuzzer_dir: &Path,
82-
core_id: CoreId,
83-
opt: &Opt,
84-
is_main_node: bool,
85-
) -> Result<(), Error>
86-
where
87-
EMH: EventManagerHooksTuple<LibaflFuzzState> + Copy + Clone,
88-
SP: ShMemProvider,
89-
{
78+
#[cfg(not(feature = "fuzzbench"))]
79+
type LibaflFuzzManager = CentralizedEventManager<
80+
LlmpRestartingEventManager<(), LibaflFuzzState, StdShMemProvider>,
81+
(),
82+
LibaflFuzzState,
83+
StdShMemProvider,
84+
>;
85+
#[cfg(feature = "fuzzbench")]
86+
type LibaflFuzzManager<F> = SimpleEventManager<SimpleMonitor<F>, LibaflFuzzState>;
87+
88+
macro_rules! define_run_client {
89+
($state: ident, $mgr: ident, $fuzzer_dir: ident, $core_id: ident, $opt:ident, $is_main_node: ident, $body:block) => {
90+
#[cfg(not(feature = "fuzzbench"))]
91+
pub fn run_client(
92+
$state: Option<LibaflFuzzState>,
93+
mut $mgr: LibaflFuzzManager,
94+
$fuzzer_dir: &Path,
95+
$core_id: CoreId,
96+
$opt: &Opt,
97+
$is_main_node: bool,
98+
) -> Result<(), Error> {
99+
$body
100+
}
101+
#[cfg(feature = "fuzzbench")]
102+
pub fn run_client<F>(
103+
$state: Option<LibaflFuzzState>,
104+
mut $mgr: LibaflFuzzManager<F>,
105+
$fuzzer_dir: &Path,
106+
$core_id: CoreId,
107+
$opt: &Opt,
108+
$is_main_node: bool,
109+
) -> Result<(), Error>
110+
where
111+
F: FnMut(&str),
112+
{
113+
$body
114+
}
115+
};
116+
}
117+
118+
define_run_client!(state, mgr, fuzzer_dir, core_id, opt, is_main_node, {
90119
// Create the shared memory map for comms with the forkserver
91120
let mut shmem_provider = UnixShMemProvider::new().unwrap();
92121
let mut shmem = shmem_provider
@@ -382,7 +411,7 @@ where
382411
.load_initial_inputs_multicore(
383412
&mut fuzzer,
384413
&mut executor,
385-
&mut restarting_mgr,
414+
&mut mgr,
386415
&[queue_dir],
387416
&core_id,
388417
opt.cores.as_ref().expect("invariant; should never occur"),
@@ -496,7 +525,7 @@ where
496525
&mut stages,
497526
&mut executor,
498527
&mut state,
499-
&mut restarting_mgr,
528+
&mut mgr,
500529
)?;
501530
} else {
502531
// The order of the stages matter!
@@ -515,12 +544,12 @@ where
515544
&mut stages,
516545
&mut executor,
517546
&mut state,
518-
&mut restarting_mgr,
547+
&mut mgr,
519548
)?;
520549
}
521550
Ok(())
522551
// TODO: serialize state when exiting.
523-
}
552+
});
524553

525554
fn base_forkserver_builder<'a>(
526555
opt: &'a Opt,
@@ -539,7 +568,7 @@ fn base_forkserver_builder<'a>(
539568
if let Some(target_env) = &opt.target_env {
540569
executor = executor.envs(target_env);
541570
}
542-
if opt.frida_mode {
571+
if opt.frida_mode || opt.unicorn_mode || opt.qemu_mode {
543572
executor = executor.kill_signal(nix::sys::signal::Signal::SIGKILL);
544573
}
545574
if let Some(kill_signal) = opt.kill_signal {

fuzzers/forkserver/libafl-fuzz/src/main.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,23 +71,27 @@ mod feedback;
7171
mod scheduler;
7272
mod stages;
7373
use clap::Parser;
74-
use corpus::{check_autoresume, create_dir_if_not_exists, remove_main_node_file};
74+
#[cfg(not(feature = "fuzzbench"))]
75+
use corpus::remove_main_node_file;
76+
use corpus::{check_autoresume, create_dir_if_not_exists};
7577
mod corpus;
7678
mod executor;
7779
mod fuzzer;
7880
mod hooks;
7981
use env_parser::parse_envs;
8082
use fuzzer::run_client;
81-
use libafl::{
82-
events::{CentralizedLauncher, EventConfig},
83-
monitors::MultiMonitor,
84-
schedulers::powersched::BaseSchedule,
85-
Error,
86-
};
87-
use libafl_bolts::{
88-
core_affinity::{CoreId, Cores},
89-
shmem::{ShMemProvider, StdShMemProvider},
90-
};
83+
#[cfg(feature = "fuzzbench")]
84+
use libafl::events::SimpleEventManager;
85+
#[cfg(not(feature = "fuzzbench"))]
86+
use libafl::events::{CentralizedLauncher, EventConfig};
87+
#[cfg(not(feature = "fuzzbench"))]
88+
use libafl::monitors::MultiMonitor;
89+
#[cfg(feature = "fuzzbench")]
90+
use libafl::monitors::SimpleMonitor;
91+
use libafl::{schedulers::powersched::BaseSchedule, Error};
92+
use libafl_bolts::core_affinity::{CoreId, Cores};
93+
#[cfg(not(feature = "fuzzbench"))]
94+
use libafl_bolts::shmem::{ShMemProvider, StdShMemProvider};
9195
use nix::sys::signal::Signal;
9296

9397
const AFL_DEFAULT_INPUT_LEN_MAX: usize = 1_048_576;
@@ -107,10 +111,14 @@ fn main() {
107111
executor::check_binary(&mut opt, SHMEM_ENV_VAR).expect("binary to be valid");
108112

109113
// Create the shared memory map provider for LLMP
114+
#[cfg(not(feature = "fuzzbench"))]
110115
let shmem_provider = StdShMemProvider::new().unwrap();
111116

112117
// Create our Monitor
118+
#[cfg(not(feature = "fuzzbench"))]
113119
let monitor = MultiMonitor::new(|s| println!("{s}"));
120+
#[cfg(feature = "fuzzbench")]
121+
let monitor = SimpleMonitor::new(|s| println!("{}", s));
114122

115123
opt.auto_resume = if opt.auto_resume {
116124
true
@@ -126,7 +134,8 @@ fn main() {
126134
// Currently, we will error if we don't find our assigned dir.
127135
// This will also not work if we use core 1-8 and then later, 16-24
128136
// since fuzzer names are using core_ids
129-
match CentralizedLauncher::builder()
137+
#[cfg(not(feature = "fuzzbench"))]
138+
let res = CentralizedLauncher::builder()
130139
.shmem_provider(shmem_provider)
131140
.configuration(EventConfig::from_name("default"))
132141
.monitor(monitor)
@@ -149,8 +158,16 @@ fn main() {
149158
.cores(&opt.cores.clone().expect("invariant; should never occur"))
150159
.broker_port(opt.broker_port.unwrap_or(AFL_DEFAULT_BROKER_PORT))
151160
.build()
152-
.launch()
153-
{
161+
.launch();
162+
#[cfg(feature = "fuzzbench")]
163+
let res = {
164+
let fuzzer_dir = opt.output_dir.join("fuzzer_main");
165+
let _ = check_autoresume(&fuzzer_dir, opt.auto_resume).unwrap();
166+
let mgr = SimpleEventManager::new(monitor);
167+
let res = run_client(None, mgr, &fuzzer_dir, CoreId(0), &opt, true);
168+
res
169+
};
170+
match res {
154171
Ok(()) => unreachable!(),
155172
Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."),
156173
Err(err) => panic!("Failed to run launcher: {err:?}"),

0 commit comments

Comments
 (0)