Feature: libafl-fuzzfuzzbench (#2689)
* fuzzbench * clippy * fmt * fix unicorn CI?
This commit is contained in:
parent
7938acc4ce
commit
d334860148
@ -36,3 +36,4 @@ libafl_nyx = { path = "../../../libafl_nyx" }
|
|||||||
[features]
|
[features]
|
||||||
default = ["track_hit_feedbacks"]
|
default = ["track_hit_feedbacks"]
|
||||||
track_hit_feedbacks = ["libafl/track_hit_feedbacks"]
|
track_hit_feedbacks = ["libafl/track_hit_feedbacks"]
|
||||||
|
fuzzbench = []
|
||||||
|
@ -65,6 +65,7 @@ script = "echo done"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"build_afl",
|
"build_afl",
|
||||||
"test_instr",
|
"test_instr",
|
||||||
|
"test_instr_fuzzbench",
|
||||||
"test_cmplog",
|
"test_cmplog",
|
||||||
"test_frida",
|
"test_frida",
|
||||||
"test_qemu",
|
"test_qemu",
|
||||||
@ -75,6 +76,10 @@ dependencies = [
|
|||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
script = "cargo build --profile ${PROFILE}"
|
script = "cargo build --profile ${PROFILE}"
|
||||||
|
|
||||||
|
[tasks.build_libafl_fuzz_fuzzbench]
|
||||||
|
script_runner = "@shell"
|
||||||
|
script = "cargo build --profile ${PROFILE} --features fuzzbench"
|
||||||
|
|
||||||
[tasks.test_instr]
|
[tasks.test_instr]
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
script = '''
|
script = '''
|
||||||
@ -108,6 +113,39 @@ test -d "./test/output/fuzzer_main/crashes" || {
|
|||||||
'''
|
'''
|
||||||
dependencies = ["build_afl", "build_libafl_fuzz"]
|
dependencies = ["build_afl", "build_libafl_fuzz"]
|
||||||
|
|
||||||
|
[tasks.test_instr_fuzzbench]
|
||||||
|
script_runner = "@shell"
|
||||||
|
script = '''
|
||||||
|
AFL_PATH=${AFL_DIR} ${AFL_CC_PATH} ./test/test-instr.c -o ./test/out-instr
|
||||||
|
|
||||||
|
export LIBAFL_DEBUG_OUTPUT=1
|
||||||
|
export AFL_CORES=0
|
||||||
|
export AFL_STATS_INTERVAL=1
|
||||||
|
|
||||||
|
timeout 5 ${FUZZER} -i ./test/seeds -o ./test/output-fuzzbench ./test/out-instr || true
|
||||||
|
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/queue/id:000002* 2>/dev/null )" || {
|
||||||
|
echo "No new corpus entries found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/fuzzer_stats 2>/dev/null )" || {
|
||||||
|
echo "No fuzzer_stats file found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
test -n "$( ls ./test/output-fuzzbench/fuzzer_main/plot_data 2>/dev/null )" || {
|
||||||
|
echo "No plot_data found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
test -d "./test/output-fuzzbench/fuzzer_main/hangs" || {
|
||||||
|
echo "No hangs directory found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
test -d "./test/output-fuzzbench/fuzzer_main/crashes" || {
|
||||||
|
echo "No crashes directory found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
dependencies = ["build_afl", "build_libafl_fuzz_fuzzbench"]
|
||||||
|
|
||||||
[tasks.test_cmplog]
|
[tasks.test_cmplog]
|
||||||
script_runner = "@shell"
|
script_runner = "@shell"
|
||||||
script = '''
|
script = '''
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, BufRead, BufReader},
|
io,
|
||||||
|
io::{BufRead, BufReader},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,6 +165,7 @@ pub fn create_dir_if_not_exists(path: &Path) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
pub fn remove_main_node_file(output_dir: &Path) -> Result<(), Error> {
|
pub fn remove_main_node_file(output_dir: &Path) -> Result<(), Error> {
|
||||||
for entry in std::fs::read_dir(output_dir)?.filter_map(Result::ok) {
|
for entry in std::fs::read_dir(output_dir)?.filter_map(Result::ok) {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
@ -7,12 +7,15 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "fuzzbench")]
|
||||||
|
use libafl::events::SimpleEventManager;
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
use libafl::events::{CentralizedEventManager, LlmpRestartingEventManager};
|
||||||
|
#[cfg(feature = "fuzzbench")]
|
||||||
|
use libafl::monitors::SimpleMonitor;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
|
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
|
||||||
events::{
|
events::ProgressReporter,
|
||||||
CentralizedEventManager, EventManagerHooksTuple, LlmpRestartingEventManager,
|
|
||||||
ProgressReporter,
|
|
||||||
},
|
|
||||||
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder},
|
executors::forkserver::{ForkserverExecutor, ForkserverExecutorBuilder},
|
||||||
feedback_and, feedback_or, feedback_or_fast,
|
feedback_and, feedback_or, feedback_or_fast,
|
||||||
feedbacks::{
|
feedbacks::{
|
||||||
@ -39,6 +42,8 @@ use libafl::{
|
|||||||
},
|
},
|
||||||
Error, Fuzzer, HasFeedback, HasMetadata, SerdeAny,
|
Error, Fuzzer, HasFeedback, HasMetadata, SerdeAny,
|
||||||
};
|
};
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
use libafl_bolts::shmem::StdShMemProvider;
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::CoreId,
|
core_affinity::CoreId,
|
||||||
current_nanos, current_time,
|
current_nanos, current_time,
|
||||||
@ -70,23 +75,47 @@ use crate::{
|
|||||||
pub type LibaflFuzzState =
|
pub type LibaflFuzzState =
|
||||||
StdState<BytesInput, CachedOnDiskCorpus<BytesInput>, StdRand, OnDiskCorpus<BytesInput>>;
|
StdState<BytesInput, CachedOnDiskCorpus<BytesInput>, StdRand, OnDiskCorpus<BytesInput>>;
|
||||||
|
|
||||||
pub fn run_client<EMH, SP>(
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
state: Option<LibaflFuzzState>,
|
type LibaflFuzzManager = CentralizedEventManager<
|
||||||
mut restarting_mgr: CentralizedEventManager<
|
LlmpRestartingEventManager<(), LibaflFuzzState, StdShMemProvider>,
|
||||||
LlmpRestartingEventManager<(), LibaflFuzzState, SP>,
|
(),
|
||||||
EMH,
|
|
||||||
LibaflFuzzState,
|
LibaflFuzzState,
|
||||||
SP,
|
StdShMemProvider,
|
||||||
>,
|
>;
|
||||||
fuzzer_dir: &Path,
|
#[cfg(feature = "fuzzbench")]
|
||||||
core_id: CoreId,
|
type LibaflFuzzManager<F> = SimpleEventManager<SimpleMonitor<F>, LibaflFuzzState>;
|
||||||
opt: &Opt,
|
|
||||||
is_main_node: bool,
|
macro_rules! define_run_client {
|
||||||
|
($state: ident, $mgr: ident, $fuzzer_dir: ident, $core_id: ident, $opt:ident, $is_main_node: ident, $body:block) => {
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
pub fn run_client(
|
||||||
|
$state: Option<LibaflFuzzState>,
|
||||||
|
mut $mgr: LibaflFuzzManager,
|
||||||
|
$fuzzer_dir: &Path,
|
||||||
|
$core_id: CoreId,
|
||||||
|
$opt: &Opt,
|
||||||
|
$is_main_node: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
#[cfg(feature = "fuzzbench")]
|
||||||
|
pub fn run_client<F>(
|
||||||
|
$state: Option<LibaflFuzzState>,
|
||||||
|
mut $mgr: LibaflFuzzManager<F>,
|
||||||
|
$fuzzer_dir: &Path,
|
||||||
|
$core_id: CoreId,
|
||||||
|
$opt: &Opt,
|
||||||
|
$is_main_node: bool,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
EMH: EventManagerHooksTuple<LibaflFuzzState> + Copy + Clone,
|
F: FnMut(&str),
|
||||||
SP: ShMemProvider,
|
|
||||||
{
|
{
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
define_run_client!(state, mgr, fuzzer_dir, core_id, opt, is_main_node, {
|
||||||
// Create the shared memory map for comms with the forkserver
|
// Create the shared memory map for comms with the forkserver
|
||||||
let mut shmem_provider = UnixShMemProvider::new().unwrap();
|
let mut shmem_provider = UnixShMemProvider::new().unwrap();
|
||||||
let mut shmem = shmem_provider
|
let mut shmem = shmem_provider
|
||||||
@ -382,7 +411,7 @@ where
|
|||||||
.load_initial_inputs_multicore(
|
.load_initial_inputs_multicore(
|
||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
&mut executor,
|
&mut executor,
|
||||||
&mut restarting_mgr,
|
&mut mgr,
|
||||||
&[queue_dir],
|
&[queue_dir],
|
||||||
&core_id,
|
&core_id,
|
||||||
opt.cores.as_ref().expect("invariant; should never occur"),
|
opt.cores.as_ref().expect("invariant; should never occur"),
|
||||||
@ -496,7 +525,7 @@ where
|
|||||||
&mut stages,
|
&mut stages,
|
||||||
&mut executor,
|
&mut executor,
|
||||||
&mut state,
|
&mut state,
|
||||||
&mut restarting_mgr,
|
&mut mgr,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
// The order of the stages matter!
|
// The order of the stages matter!
|
||||||
@ -515,12 +544,12 @@ where
|
|||||||
&mut stages,
|
&mut stages,
|
||||||
&mut executor,
|
&mut executor,
|
||||||
&mut state,
|
&mut state,
|
||||||
&mut restarting_mgr,
|
&mut mgr,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
// TODO: serialize state when exiting.
|
// TODO: serialize state when exiting.
|
||||||
}
|
});
|
||||||
|
|
||||||
fn base_forkserver_builder<'a>(
|
fn base_forkserver_builder<'a>(
|
||||||
opt: &'a Opt,
|
opt: &'a Opt,
|
||||||
@ -539,7 +568,7 @@ fn base_forkserver_builder<'a>(
|
|||||||
if let Some(target_env) = &opt.target_env {
|
if let Some(target_env) = &opt.target_env {
|
||||||
executor = executor.envs(target_env);
|
executor = executor.envs(target_env);
|
||||||
}
|
}
|
||||||
if opt.frida_mode {
|
if opt.frida_mode || opt.unicorn_mode || opt.qemu_mode {
|
||||||
executor = executor.kill_signal(nix::sys::signal::Signal::SIGKILL);
|
executor = executor.kill_signal(nix::sys::signal::Signal::SIGKILL);
|
||||||
}
|
}
|
||||||
if let Some(kill_signal) = opt.kill_signal {
|
if let Some(kill_signal) = opt.kill_signal {
|
||||||
|
@ -71,23 +71,27 @@ mod feedback;
|
|||||||
mod scheduler;
|
mod scheduler;
|
||||||
mod stages;
|
mod stages;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use corpus::{check_autoresume, create_dir_if_not_exists, remove_main_node_file};
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
use corpus::remove_main_node_file;
|
||||||
|
use corpus::{check_autoresume, create_dir_if_not_exists};
|
||||||
mod corpus;
|
mod corpus;
|
||||||
mod executor;
|
mod executor;
|
||||||
mod fuzzer;
|
mod fuzzer;
|
||||||
mod hooks;
|
mod hooks;
|
||||||
use env_parser::parse_envs;
|
use env_parser::parse_envs;
|
||||||
use fuzzer::run_client;
|
use fuzzer::run_client;
|
||||||
use libafl::{
|
#[cfg(feature = "fuzzbench")]
|
||||||
events::{CentralizedLauncher, EventConfig},
|
use libafl::events::SimpleEventManager;
|
||||||
monitors::MultiMonitor,
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
schedulers::powersched::BaseSchedule,
|
use libafl::events::{CentralizedLauncher, EventConfig};
|
||||||
Error,
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
};
|
use libafl::monitors::MultiMonitor;
|
||||||
use libafl_bolts::{
|
#[cfg(feature = "fuzzbench")]
|
||||||
core_affinity::{CoreId, Cores},
|
use libafl::monitors::SimpleMonitor;
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
use libafl::{schedulers::powersched::BaseSchedule, Error};
|
||||||
};
|
use libafl_bolts::core_affinity::{CoreId, Cores};
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
use libafl_bolts::shmem::{ShMemProvider, StdShMemProvider};
|
||||||
use nix::sys::signal::Signal;
|
use nix::sys::signal::Signal;
|
||||||
|
|
||||||
const AFL_DEFAULT_INPUT_LEN_MAX: usize = 1_048_576;
|
const AFL_DEFAULT_INPUT_LEN_MAX: usize = 1_048_576;
|
||||||
@ -107,10 +111,14 @@ fn main() {
|
|||||||
executor::check_binary(&mut opt, SHMEM_ENV_VAR).expect("binary to be valid");
|
executor::check_binary(&mut opt, SHMEM_ENV_VAR).expect("binary to be valid");
|
||||||
|
|
||||||
// Create the shared memory map provider for LLMP
|
// Create the shared memory map provider for LLMP
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
let shmem_provider = StdShMemProvider::new().unwrap();
|
let shmem_provider = StdShMemProvider::new().unwrap();
|
||||||
|
|
||||||
// Create our Monitor
|
// Create our Monitor
|
||||||
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
let monitor = MultiMonitor::new(|s| println!("{s}"));
|
let monitor = MultiMonitor::new(|s| println!("{s}"));
|
||||||
|
#[cfg(feature = "fuzzbench")]
|
||||||
|
let monitor = SimpleMonitor::new(|s| println!("{}", s));
|
||||||
|
|
||||||
opt.auto_resume = if opt.auto_resume {
|
opt.auto_resume = if opt.auto_resume {
|
||||||
true
|
true
|
||||||
@ -126,7 +134,8 @@ fn main() {
|
|||||||
// Currently, we will error if we don't find our assigned dir.
|
// Currently, we will error if we don't find our assigned dir.
|
||||||
// This will also not work if we use core 1-8 and then later, 16-24
|
// This will also not work if we use core 1-8 and then later, 16-24
|
||||||
// since fuzzer names are using core_ids
|
// since fuzzer names are using core_ids
|
||||||
match CentralizedLauncher::builder()
|
#[cfg(not(feature = "fuzzbench"))]
|
||||||
|
let res = CentralizedLauncher::builder()
|
||||||
.shmem_provider(shmem_provider)
|
.shmem_provider(shmem_provider)
|
||||||
.configuration(EventConfig::from_name("default"))
|
.configuration(EventConfig::from_name("default"))
|
||||||
.monitor(monitor)
|
.monitor(monitor)
|
||||||
@ -149,8 +158,16 @@ fn main() {
|
|||||||
.cores(&opt.cores.clone().expect("invariant; should never occur"))
|
.cores(&opt.cores.clone().expect("invariant; should never occur"))
|
||||||
.broker_port(opt.broker_port.unwrap_or(AFL_DEFAULT_BROKER_PORT))
|
.broker_port(opt.broker_port.unwrap_or(AFL_DEFAULT_BROKER_PORT))
|
||||||
.build()
|
.build()
|
||||||
.launch()
|
.launch();
|
||||||
{
|
#[cfg(feature = "fuzzbench")]
|
||||||
|
let res = {
|
||||||
|
let fuzzer_dir = opt.output_dir.join("fuzzer_main");
|
||||||
|
let _ = check_autoresume(&fuzzer_dir, opt.auto_resume).unwrap();
|
||||||
|
let mgr = SimpleEventManager::new(monitor);
|
||||||
|
let res = run_client(None, mgr, &fuzzer_dir, CoreId(0), &opt, true);
|
||||||
|
res
|
||||||
|
};
|
||||||
|
match res {
|
||||||
Ok(()) => unreachable!(),
|
Ok(()) => unreachable!(),
|
||||||
Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."),
|
Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."),
|
||||||
Err(err) => panic!("Failed to run launcher: {err:?}"),
|
Err(err) => panic!("Failed to run launcher: {err:?}"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user