From 7326c2da3149874f7ba7c22353eb65f0cb0a7131 Mon Sep 17 00:00:00 2001 From: Kevin Valerio Date: Wed, 19 Jun 2024 16:23:58 +0200 Subject: [PATCH 1/4] Building in release mode is now possible --- src/bin/cargo-ziggy/build.rs | 32 +++++++++++++++++++++------ src/bin/cargo-ziggy/fuzz.rs | 20 +++++++++-------- src/bin/cargo-ziggy/main.rs | 38 ++++++++++++++++++++++++++------- src/bin/cargo-ziggy/minimize.rs | 1 + 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 57bf36a..55940a3 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -17,15 +17,22 @@ impl Build { if !self.no_afl { eprintln!(" {} afl", style("Building").red().bold()); + let mut afl_args = vec![ + "afl", + "build", + "--features=ziggy/afl", + "--target-dir=target/afl", + ]; + + // Add the --release argument if self.release is true + if self.release { + afl_args.push("--release"); + info!("Building in release mode"); + } // Second fuzzer we build: AFL++ let run = process::Command::new(cargo.clone()) - .args([ - "afl", - "build", - "--features=ziggy/afl", - "--target-dir=target/afl", - ]) + .args(afl_args) .env("AFL_QUIET", "1") .env("AFL_LLVM_CMPGLOG", "1") // for afl.rs feature "plugins" .env("RUSTFLAGS", env::var("RUSTFLAGS").unwrap_or_default()) @@ -46,9 +53,20 @@ impl Build { if !self.no_honggfuzz { eprintln!(" {} honggfuzz", style("Building").red().bold()); + let mut hfuzz_args = vec![ + "hfuzz", + "build", + ]; + + // Add the --release argument if self.release is true + if self.release { + hfuzz_args.push("--release"); + info!("Building in release mode"); + } + // Third fuzzer we build: Honggfuzz let run = process::Command::new(cargo) - .args(["hfuzz", "build"]) + .args(hfuzz_args) .env("CARGO_TARGET_DIR", "./target/honggfuzz") .env("HFUZZ_BUILD_ARGS", "--features=ziggy/honggfuzz") .env("RUSTFLAGS", env::var("RUSTFLAGS").unwrap_or_default()) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 9bba873..8bc2329 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -46,7 +46,7 @@ impl Fuzz { } pub fn corpus_minimized(&self) -> String { - format!("{}/corpus_minimized/", self.output_target(),) + format!("{}/corpus_minimized/", self.output_target(), ) } pub fn output_target(&self) -> String { @@ -68,6 +68,7 @@ impl Fuzz { let build = Build { no_afl: !self.afl(), no_honggfuzz: !self.honggfuzz(), + release: self.release, }; build.build().context("Failed to build the fuzzers")?; @@ -172,7 +173,7 @@ impl Fuzz { self.output_target(), self.target ) - .into()]); + .into()]); for crash_dir in crash_dirs { if let Ok(crashes) = fs::read_dir(crash_dir) { @@ -181,7 +182,7 @@ impl Fuzz { let to_path = crash_path.join(&file_name); if to_path.exists() || ["", "README.txt", "HONGGFUZZ.REPORT.TXT", "input"] - .contains(&file_name.to_str().unwrap_or_default()) + .contains(&file_name.to_str().unwrap_or_default()) { continue; } @@ -198,7 +199,7 @@ impl Fuzz { "{}/afl/mainaflfuzzer/queue/*", self.output_target(), ))? - .flatten(); + .flatten(); for file in afl_corpus { if let Some((file_id, file_name)) = extract_file_id(&file) { if file_id > last_synced_queue_id { @@ -362,8 +363,8 @@ impl Fuzz { &timeout_option_afl, &dictionary_option, ] - .iter() - .filter(|a| a != &&""), + .iter() + .filter(|a| a != &&""), ) .args(self.afl_flags.clone()) .arg(format!("./target/afl/debug/{}", self.target)) @@ -404,8 +405,8 @@ impl Fuzz { .unwrap_or_default() .contains("dynamic_input") && !std::str::from_utf8(hfuzz_help.stderr.as_slice()) - .unwrap_or_default() - .contains("dynamic_input") + .unwrap_or_default() + .contains("dynamic_input") { return Err(anyhow!("Outdated version of honggfuzz, please update the ziggy version in your Cargo.toml or rebuild the project")); } @@ -483,7 +484,7 @@ impl Fuzz { "tail -f {}/logs/honggfuzz.log", self.output_target() )) - .bold() + .bold() ); } @@ -790,6 +791,7 @@ impl FuzzingConfig { } use std::fmt; + impl fmt::Display for FuzzingConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self) diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index 455b9e9..ef58019 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -95,6 +95,10 @@ pub struct Build { /// No honggfuzz (Fuzz only with AFL++) #[clap(long = "no-honggfuzz", action)] no_honggfuzz: bool, + + /// Compile in release mode (--release) + #[clap(long = "release", action)] + release: bool, } #[derive(Args)] @@ -111,8 +115,14 @@ pub struct Fuzz { #[clap(short, long, value_parser, value_name = "DIR")] initial_corpus: Option, + /// Compile in release mode (--release) + #[clap(long = "release", action)] + release: bool, + /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, /// Number of concurent fuzzing jobs @@ -148,7 +158,7 @@ pub struct Fuzz { no_honggfuzz: bool, // This value helps us create a global timer for our display - #[clap(skip=std::time::Instant::now())] + #[clap(skip = std::time::Instant::now())] start_time: std::time::Instant, /// Pass flags to AFL++ directly @@ -179,7 +189,9 @@ pub struct Run { recursive: bool, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, } @@ -198,7 +210,9 @@ pub struct Minimize { output_corpus: PathBuf, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, /// Number of concurent minimizing jobs (AFL++ only) @@ -224,7 +238,9 @@ pub struct Cover { input: PathBuf, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, /// Source directory of covered code @@ -255,7 +271,9 @@ pub struct Plot { output: PathBuf, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, } @@ -274,7 +292,9 @@ pub struct Triage { jobs: u32, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, /* future feature, wait for casr /// Crash directory to be sourced from @@ -294,7 +314,9 @@ pub struct AddSeeds { input: PathBuf, /// Fuzzers output directory - #[clap(short, long, env="ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value=DEFAULT_OUTPUT_DIR)] + #[clap( + short, long, env = "ZIGGY_OUTPUT", value_parser, value_name = "DIR", default_value = DEFAULT_OUTPUT_DIR + )] ziggy_output: PathBuf, } diff --git a/src/bin/cargo-ziggy/minimize.rs b/src/bin/cargo-ziggy/minimize.rs index 2e92c12..ff2f7a8 100644 --- a/src/bin/cargo-ziggy/minimize.rs +++ b/src/bin/cargo-ziggy/minimize.rs @@ -7,6 +7,7 @@ impl Minimize { let build = Build { no_afl: self.engine == FuzzingEngines::Honggfuzz, no_honggfuzz: self.engine == FuzzingEngines::AFLPlusPlus, + release: false, }; build.build().context("Failed to build the fuzzers")?; From 44be82efa844c30790593d71928699a87cf4e694 Mon Sep 17 00:00:00 2001 From: Kevin Valerio Date: Thu, 20 Jun 2024 10:35:58 +0200 Subject: [PATCH 2/4] fmt --- src/bin/cargo-ziggy/build.rs | 5 +---- src/bin/cargo-ziggy/fuzz.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 55940a3..2da548c 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -53,10 +53,7 @@ impl Build { if !self.no_honggfuzz { eprintln!(" {} honggfuzz", style("Building").red().bold()); - let mut hfuzz_args = vec![ - "hfuzz", - "build", - ]; + let mut hfuzz_args = vec!["hfuzz", "build"]; // Add the --release argument if self.release is true if self.release { diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 8bc2329..d7112a8 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -46,7 +46,7 @@ impl Fuzz { } pub fn corpus_minimized(&self) -> String { - format!("{}/corpus_minimized/", self.output_target(), ) + format!("{}/corpus_minimized/", self.output_target(),) } pub fn output_target(&self) -> String { @@ -173,7 +173,7 @@ impl Fuzz { self.output_target(), self.target ) - .into()]); + .into()]); for crash_dir in crash_dirs { if let Ok(crashes) = fs::read_dir(crash_dir) { @@ -182,7 +182,7 @@ impl Fuzz { let to_path = crash_path.join(&file_name); if to_path.exists() || ["", "README.txt", "HONGGFUZZ.REPORT.TXT", "input"] - .contains(&file_name.to_str().unwrap_or_default()) + .contains(&file_name.to_str().unwrap_or_default()) { continue; } @@ -199,7 +199,7 @@ impl Fuzz { "{}/afl/mainaflfuzzer/queue/*", self.output_target(), ))? - .flatten(); + .flatten(); for file in afl_corpus { if let Some((file_id, file_name)) = extract_file_id(&file) { if file_id > last_synced_queue_id { @@ -363,8 +363,8 @@ impl Fuzz { &timeout_option_afl, &dictionary_option, ] - .iter() - .filter(|a| a != &&""), + .iter() + .filter(|a| a != &&""), ) .args(self.afl_flags.clone()) .arg(format!("./target/afl/debug/{}", self.target)) @@ -405,8 +405,8 @@ impl Fuzz { .unwrap_or_default() .contains("dynamic_input") && !std::str::from_utf8(hfuzz_help.stderr.as_slice()) - .unwrap_or_default() - .contains("dynamic_input") + .unwrap_or_default() + .contains("dynamic_input") { return Err(anyhow!("Outdated version of honggfuzz, please update the ziggy version in your Cargo.toml or rebuild the project")); } @@ -484,7 +484,7 @@ impl Fuzz { "tail -f {}/logs/honggfuzz.log", self.output_target() )) - .bold() + .bold() ); } From 16c6b43b8ac4571a4ed2062e4bd157a2eeae8810 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 2 Sep 2024 10:28:32 +0200 Subject: [PATCH 3/4] Fix clippy for CI --- Cargo.toml | 3 +++ examples/url/Cargo.toml | 3 +++ examples/url/src/main.rs | 2 +- src/bin/cargo-ziggy/fuzz.rs | 2 +- tests/arbitrary_fuzz.rs | 2 +- tests/url_fuzz.rs | 2 +- 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d251cd8..48862fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,3 +45,6 @@ cli = [ "cargo_metadata", ] coverage = ["fork", "libc"] + +[lints.clippy] +needless_doctest_main = "allow" \ No newline at end of file diff --git a/examples/url/Cargo.toml b/examples/url/Cargo.toml index 51eb1f6..b19ce17 100644 --- a/examples/url/Cargo.toml +++ b/examples/url/Cargo.toml @@ -7,3 +7,6 @@ publish = false [dependencies] url = "2.5.0" ziggy = { path = "../../", default-features = false } + +[features] +fuzzing = [] \ No newline at end of file diff --git a/examples/url/src/main.rs b/examples/url/src/main.rs index b468195..ef3586f 100644 --- a/examples/url/src/main.rs +++ b/examples/url/src/main.rs @@ -11,7 +11,7 @@ // could assert that a certain value satisfies a property. fn invariant_fuzz(data: &str) { if let Ok(parsed) = url::Url::parse(data) { - #[cfg(not(fuzzing))] + #[cfg(not(feature = "fuzzing"))] println!("{data} => {parsed}"); // We assert that the string representation of the URL always contains a ':' // character. diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index d7112a8..acf1298 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -800,7 +800,7 @@ impl fmt::Display for FuzzingConfig { pub fn kill_subprocesses_recursively(pid: &str) -> Result<(), Error> { let subprocesses = process::Command::new("pgrep") - .arg(&format!("-P{pid}")) + .arg(format!("-P{pid}")) .output()?; for subprocess in std::str::from_utf8(&subprocesses.stdout)?.split('\n') { diff --git a/tests/arbitrary_fuzz.rs b/tests/arbitrary_fuzz.rs index 5c81286..9dc8152 100644 --- a/tests/arbitrary_fuzz.rs +++ b/tests/arbitrary_fuzz.rs @@ -7,7 +7,7 @@ use std::{ fn kill_subprocesses_recursively(pid: &str) { let subprocesses = process::Command::new("pgrep") - .arg(&format!("-P{pid}")) + .arg(format!("-P{pid}")) .output() .unwrap(); diff --git a/tests/url_fuzz.rs b/tests/url_fuzz.rs index 2ff51b8..8609ecd 100644 --- a/tests/url_fuzz.rs +++ b/tests/url_fuzz.rs @@ -7,7 +7,7 @@ use std::{ fn kill_subprocesses_recursively(pid: &str) { let subprocesses = process::Command::new("pgrep") - .arg(&format!("-P{pid}")) + .arg(format!("-P{pid}")) .output() .unwrap(); From 0b613ef927144ff3285a65eeaf8c21ada9c562e5 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 2 Sep 2024 10:32:18 +0200 Subject: [PATCH 4/4] Add newline at end of Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 48862fe..621b422 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,4 +47,4 @@ cli = [ coverage = ["fork", "libc"] [lints.clippy] -needless_doctest_main = "allow" \ No newline at end of file +needless_doctest_main = "allow"