diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 1a2cfcd7d5..a947e7d14e 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -63,7 +63,7 @@ jobs: # cargo-hack's --feature-powerset would be nice here but libafl has a too many knobs - name: Check each feature # Skipping python as it has to be built with the `maturin` tool - run: cargo hack check --feature-powerset --depth=2 --exclude-features=agpl,nautilus,python,sancov_pcguard_edges --no-dev-deps + run: cargo hack check --feature-powerset --depth=2 --exclude-features=agpl,nautilus,python,sancov_pcguard_edges,arm,aarch64,i386 --no-dev-deps # pcguard edges and pcguard hitcounts are not compatible and we need to build them seperately - name: Check pcguard edges run: cargo check --features=sancov_pcguard_edges diff --git a/fuzzers/qemu_launcher/Cargo.toml b/fuzzers/qemu_launcher/Cargo.toml index 5426c25948..a66963ee78 100644 --- a/fuzzers/qemu_launcher/Cargo.toml +++ b/fuzzers/qemu_launcher/Cargo.toml @@ -16,4 +16,4 @@ debug = true [dependencies] libafl = { path = "../../libafl/" } -libafl_qemu = { path = "../../libafl_qemu/" } +libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] } diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index 9241334d8f..e5d5ffa476 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -218,7 +218,6 @@ impl InProcessHandlers { } } - #[must_use] pub fn new() -> Result where I: Input, diff --git a/libafl/src/stages/concolic.rs b/libafl/src/stages/concolic.rs index 2d41fb650d..adbedd751e 100644 --- a/libafl/src/stages/concolic.rs +++ b/libafl/src/stages/concolic.rs @@ -246,7 +246,7 @@ fn generate_mutations(iter: impl Iterator) -> Vec< assert_eq!(bits_to_insert % 8, 0, "can only insert full bytes"); let after_len = (u64::from(target.get_size()) / 8) - offset - (bits_to_insert / 8); Some( - std::array::IntoIter::new([ + [ if offset == 0 { None } else { @@ -267,7 +267,8 @@ fn generate_mutations(iter: impl Iterator) -> Vec< false, )) }, - ]) + ] + .into_iter() .reduce(|acc: Option, val: Option| match (acc, val) { (Some(prev), Some(next)) => Some(prev.concat(&next)), (Some(prev), None) => Some(prev), diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index afc2cabf68..18cd38d341 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -14,6 +14,14 @@ edition = "2021" python = ["pyo3", "pyo3-build-config"] default = [] +# The following architecture features are mutually exclusive. +x86_64 = [] # build qemu for x86_64 (default) +i386 = [] # build qemu for i386 +arm = [] # build qemu for arm +aarch64 = [] # build qemu for aarch64 + +clippy = [] # special feature for clippy, don't use in normal projects§ + [dependencies] libafl = { path = "../libafl", version = "0.7.0" } libafl_targets = { path = "../libafl_targets", version = "0.7.0" } diff --git a/libafl_qemu/build.rs b/libafl_qemu/build.rs index d8362f813b..ecf81e3cbf 100644 --- a/libafl_qemu/build.rs +++ b/libafl_qemu/build.rs @@ -11,12 +11,24 @@ fn build_dep_check(tools: &[&str]) { } } +#[macro_export] +macro_rules! assert_unique_feature { + () => {}; + ($first:tt $(,$rest:tt)*) => { + $( + #[cfg(not(feature = "clippy"))] // ignore multiple definition for clippy + #[cfg(all(feature = $first, feature = $rest))] + compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together")); + )* + assert_unique_feature!($($rest),*); + } +} + #[allow(clippy::too_many_lines)] fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=src/asan-giovese.c"); println!("cargo:rerun-if-changed=src/asan-giovese.h"); - println!("cargo:rerun-if-env-changed=CPU_TARGET"); println!("cargo:rerun-if-env-changed=CROSS_CC"); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); @@ -24,13 +36,40 @@ fn main() { return; } + // Make sure we have at least and at most one architecutre feature set + // Else, we default to `x86_64` - having a default makes CI easier :) + assert_unique_feature!("arm", "aarch64", "i386", "i86_64"); + #[cfg(not(any( + feature = "arm", + feature = "aarch64", + feature = "i386", + feature = "x86_64" + )))] + println!( + "cargo:warning=No architecture feature enabled for libafl_qemu, supported: arm, aarch64, i386, x86_64 - defaulting to x86_64" + ); + + let cpu_target = if cfg!(feature = "clippy") { + // assume x86_64 for clippy + "x86_64" + } else if cfg!(feature = "arm") { + "arm" + } else if cfg!(feature = "aarch64") { + "aarch64" + } else if cfg!(feature = "i386") { + "368" + } else { + // if cfg!(feature = "x86_64") { + "x86_64" + /*} else { + panic!("No architecture feture enabled for libafl_qemu"); + */ + }; + let jobs = env::var("CARGO_BUILD_JOBS"); - let cpu_target = env::var("CPU_TARGET").unwrap_or_else(|_| { - println!("cargo:warning=CPU_TARGET is not set, default to x86_64"); - "x86_64".to_owned() - }); + let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| { - println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if CPU_TARGET is not the host arch)"); + println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if the selected cpu target ({}) is not the host arch ({}))", cpu_target, env::consts::ARCH); "cc".to_owned() }); diff --git a/libafl_qemu/src/lib.rs b/libafl_qemu/src/lib.rs index cc24ecd728..a70c76d3cd 100644 --- a/libafl_qemu/src/lib.rs +++ b/libafl_qemu/src/lib.rs @@ -1,17 +1,40 @@ use std::env; +#[cfg(feature = "aarch64")] pub mod aarch64; -pub mod arm; -pub mod i386; -pub mod x86_64; - -#[cfg(cpu_target = "aarch64")] +#[cfg(all(feature = "aarch64", not(feature = "clippy")))] pub use aarch64::*; -#[cfg(cpu_target = "arm")] + +#[cfg(feature = "arm")] +pub mod arm; +#[cfg(all(feature = "arm", not(feature = "clippy")))] pub use arm::*; -#[cfg(cpu_target = "i386")] + +#[cfg(feature = "i386")] +pub mod i386; +#[cfg(all(feature = "i386", not(feature = "clippy")))] pub use i386::*; -#[cfg(cpu_target = "x86_64")] + +// We default to x86_64, having a default makes CI easier :) +#[cfg(any( + feature = "x86_64", + not(any( + feature = "arm", + feature = "aarch64", + feature = "i386", + feature = "x86_64" + )) +))] +pub mod x86_64; +#[cfg(any( + feature = "x86_64", + not(any( + feature = "arm", + feature = "aarch64", + feature = "i386", + feature = "x86_64" + )) +))] pub use x86_64::*; pub mod elf;