diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 5b21782..ce5fa7d 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -76,8 +76,8 @@ impl Build { } if !self.no_honggfuzz { - assert_eq!( - self.no_afl, self.asan, + assert!( + !self.asan, "Cannot build honggfuzz with ASAN for the moment. use --no-honggfuzz" ); eprintln!(" {} honggfuzz", style("Building").red().bold()); diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index f327c7a..2ab9a2a 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -578,9 +578,7 @@ impl Fuzz { .map_or(String::from("err"), |corpus| format!("{}", corpus.count())); let engine = match (self.no_afl, self.no_honggfuzz, self.jobs) { - (false, false, 1) => FuzzingEngines::AFLPlusPlus, - (false, false, _) => FuzzingEngines::All, - (false, true, _) => FuzzingEngines::AFLPlusPlus, + (false, _, _) => FuzzingEngines::AFLPlusPlus, (true, false, _) => FuzzingEngines::Honggfuzz, (true, true, _) => return Err(anyhow!("Pick at least one fuzzer")), }; diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index 1e6c57a..4e2ae6b 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -27,7 +27,6 @@ pub const DEFAULT_UNMODIFIED_TARGET: &str = "automatically guessed"; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] pub enum FuzzingEngines { - All, AFLPlusPlus, Honggfuzz, } @@ -239,7 +238,7 @@ pub struct Minimize { #[clap(short, long, value_name = "NUM", default_value_t = 1)] jobs: u32, - #[clap(short, long, value_enum, default_value_t = FuzzingEngines::All)] + #[clap(short, long, value_enum, default_value_t = FuzzingEngines::AFLPlusPlus)] engine: FuzzingEngines, } diff --git a/src/bin/cargo-ziggy/minimize.rs b/src/bin/cargo-ziggy/minimize.rs index 0e3637c..134e18e 100644 --- a/src/bin/cargo-ziggy/minimize.rs +++ b/src/bin/cargo-ziggy/minimize.rs @@ -1,6 +1,10 @@ use crate::{find_target, Build, FuzzingEngines, Minimize}; use anyhow::{Context, Result}; -use std::{env, fs::File, process, thread, time::Duration}; +use std::{ + env, + fs::{self, File}, + process, +}; impl Minimize { pub fn minimize(&mut self) -> Result<(), anyhow::Error> { @@ -17,22 +21,11 @@ impl Minimize { info!("Minimizing corpus"); - match self.engine { - FuzzingEngines::All => { - let min_afl = self.clone(); - let handle_afl = thread::spawn(move || { - min_afl.minimize_afl().unwrap(); - }); - thread::sleep(Duration::from_millis(1000)); - - let min_honggfuzz = self.clone(); - let handle_honggfuzz = thread::spawn(move || { - min_honggfuzz.minimize_honggfuzz().unwrap(); - }); + let entries = fs::read_dir(self.input_corpus())?; + let original_count = entries.filter_map(|entry| entry.ok()).count(); + println!("Running minimization on a corpus of {original_count} files"); - handle_afl.join().unwrap(); - handle_honggfuzz.join().unwrap(); - } + match self.engine { FuzzingEngines::AFLPlusPlus => { self.minimize_afl()?; } @@ -40,12 +33,33 @@ impl Minimize { self.minimize_honggfuzz()?; } } + + let min_entries = fs::read_dir(self.output_corpus())?; + let minimized_count = min_entries.filter_map(|entry| entry.ok()).count(); + println!("Minimized corpus contains {minimized_count} files"); + Ok(()) } + fn input_corpus(&self) -> String { + self.input_corpus + .display() + .to_string() + .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) + .replace("{target_name}", &self.target) + } + + fn output_corpus(&self) -> String { + self.output_corpus + .display() + .to_string() + .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) + .replace("{target_name}", &self.target) + } + // AFL++ minimization fn minimize_afl(&self) -> Result<(), anyhow::Error> { - info!("Minimizing with AFL++"); + println!("Minimizing with AFL++"); // The cargo executable let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); @@ -60,19 +74,9 @@ impl Minimize { "afl", "cmin", "-i", - &self - .input_corpus - .display() - .to_string() - .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) - .replace("{target_name}", &self.target), + &self.input_corpus(), "-o", - &self - .output_corpus - .display() - .to_string() - .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) - .replace("{target_name}", &self.target), + &self.output_corpus(), "-T", &jobs_option, "--", @@ -95,7 +99,7 @@ impl Minimize { // HONGGFUZZ minimization fn minimize_honggfuzz(&self) -> Result<(), anyhow::Error> { - info!("Minimizing with honggfuzz"); + println!("Minimizing with honggfuzz"); // The cargo executable let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); @@ -113,19 +117,7 @@ impl Minimize { ) .env( "HFUZZ_RUN_ARGS", - format!( - "-i{} -M -o{}", - self.input_corpus - .display() - .to_string() - .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) - .replace("{target_name}", &self.target), - self.output_corpus - .display() - .to_string() - .replace("{ziggy_output}", &self.ziggy_output.display().to_string()) - .replace("{target_name}", &self.target), - ), + format!("-i{} -M -o{}", &self.input_corpus(), &self.output_corpus(),), ) .stderr(File::create(format!( "{}/{}/logs/minimization_honggfuzz.log", diff --git a/tests/url_fuzz.rs b/tests/url_fuzz.rs index bde9e3a..b2ee361 100644 --- a/tests/url_fuzz.rs +++ b/tests/url_fuzz.rs @@ -118,6 +118,18 @@ fn integration() { .join("logs") .join("minimization_afl.log") .is_file()); + + // cargo ziggy minimize -e honggfuzz + let minimization = process::Command::new(&cargo_ziggy) + .arg("ziggy") + .arg("minimize") + .arg("-ehonggfuzz") + .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) + .current_dir(&fuzzer_directory) + .status() + .expect("failed to run `cargo ziggy minimize`"); + + assert!(minimization.success()); assert!(temp_dir_path .join("url-fuzz") .join("logs")