From 09e32b023903e0d8f98f2d58405c9bbc8f846604 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Thu, 4 May 2023 16:17:50 +0200 Subject: [PATCH] added cli flags to enable "--careful" mode inspired by `cargo careful` * based on [this PR](https://github.com/rust-fuzz/cargo-fuzz/pull/292) to `cargo-fuzz` by @saethlin * based on [cargo-careful](https://github.com/RalfJung/cargo-careful) by @RalfJung --- cargo-libafl/src/options.rs | 15 +++++++++++++++ cargo-libafl/src/options/coverage.rs | 9 ++++++++- cargo-libafl/src/project.rs | 11 ++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/cargo-libafl/src/options.rs b/cargo-libafl/src/options.rs index 6597c1f..140a565 100644 --- a/cargo-libafl/src/options.rs +++ b/cargo-libafl/src/options.rs @@ -98,6 +98,19 @@ pub struct BuildOptions { /// Use a specific sanitizer pub sanitizer: Sanitizer, + #[clap(long = "build-std")] + /// Pass `-Zbuild-std` to cargo to build the standard library with the same build settings as + /// the fuzz target, such as debug assertions and sanitizers. This allows to identify a more + /// diverse set of bugs. But beware, some sanitizers might cause false alarms with the standard + /// library (e.g., thread sanitizer). Currently this conflicts with source-based coverage + /// instrumentation. + pub build_std: bool, + + #[clap(short, long = "careful")] + /// enable "careful" mode: inspired by https://github.com/RalfJung/cargo-careful, this enables building the + /// standard library (implies --build-std) with debug assertions and extra const UB and init checks. + pub careful_mode: bool, + #[clap( name = "triple", long = "target", @@ -229,6 +242,8 @@ mod test { no_default_features: false, all_features: false, features: None, + build_std: false, + careful_mode: false, sanitizer: Sanitizer::Address, triple: String::from(crate::utils::default_target()), unstable_flags: Vec::new(), diff --git a/cargo-libafl/src/options/coverage.rs b/cargo-libafl/src/options/coverage.rs index b8ca7ea..b2c3bf9 100644 --- a/cargo-libafl/src/options/coverage.rs +++ b/cargo-libafl/src/options/coverage.rs @@ -3,7 +3,7 @@ use crate::{ project::FuzzProject, RunCommand, }; -use anyhow::Result; +use anyhow::{bail, Result}; use clap::{self, Parser}; #[derive(Clone, Debug, Parser)] @@ -27,6 +27,13 @@ pub struct Coverage { impl RunCommand for Coverage { fn run_command(&mut self) -> Result<()> { + if self.build.build_std { + bail!( + "-Zbuild-std is currently incompatible with -Zinstrument-coverage, \ + see https://github.com/rust-lang/wg-cargo-std-aware/issues/63" + ); + } + let project = FuzzProject::new(self.fuzz_dir_wrapper.fuzz_dir.clone())?; self.build.coverage = true; project.exec_coverage(self) diff --git a/cargo-libafl/src/project.rs b/cargo-libafl/src/project.rs index 647cab0..c89c9ca 100644 --- a/cargo-libafl/src/project.rs +++ b/cargo-libafl/src/project.rs @@ -159,7 +159,9 @@ impl FuzzProject { for flag in &build.unstable_flags { cmd.arg("-Z").arg(flag); } - if let Sanitizer::Memory = build.sanitizer { + if (matches!(build.sanitizer, Sanitizer::Memory) || build.build_std || build.careful_mode) + && !build.coverage + { cmd.arg("-Z").arg("build-std"); } @@ -202,8 +204,11 @@ impl FuzzProject { if build.triple.contains("-linux-") { rustflags.push_str(" -Cllvm-args=-sanitizer-coverage-stack-depth"); } - if !build.release || build.debug_assertions { - rustflags.push_str(" -Cdebug-assertions"); + if build.careful_mode { + rustflags.push_str(" -Zextra-const-ub-checks -Zstrict-init-checks --cfg careful"); + } + if !build.release || build.debug_assertions || build.careful_mode { + rustflags.push_str(" -Cdebug-assertions=on"); } if build.triple.contains("-msvc") { // The entrypoint is in the bundled libfuzzer rlib, this gets the linker to find it.