Add Features for C Targets (#1663)
* Allow disabling C targets for platforms that dont support them when using cmp observers * Make sancov depend on coverage
This commit is contained in:
parent
c84629a2f8
commit
5d5ee40329
@ -9,31 +9,49 @@ readme = "../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing"]
|
keywords = ["fuzzing", "testing"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
|
categories = [
|
||||||
|
"development-tools::testing",
|
||||||
|
"emulators",
|
||||||
|
"embedded",
|
||||||
|
"os",
|
||||||
|
"no-std",
|
||||||
|
]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "sanitizers_flags"]
|
default = [
|
||||||
|
"std",
|
||||||
|
"sanitizers_flags",
|
||||||
|
"windows_asan",
|
||||||
|
"forkserver",
|
||||||
|
"cmplog",
|
||||||
|
"coverage",
|
||||||
|
"common",
|
||||||
|
]
|
||||||
std = ["libafl/std"]
|
std = ["libafl/std"]
|
||||||
libfuzzer = ["std", "sanitizer_interfaces"]
|
libfuzzer = ["std", "common", "sanitizer_interfaces"]
|
||||||
libfuzzer_no_link_main = ["libfuzzer"]
|
libfuzzer_no_link_main = ["libfuzzer"]
|
||||||
libfuzzer_define_run_driver = ["libfuzzer"]
|
libfuzzer_define_run_driver = ["libfuzzer"]
|
||||||
libfuzzer_interceptors = ["libfuzzer", "sancov_cmplog"]
|
libfuzzer_interceptors = ["libfuzzer", "sancov_cmplog"]
|
||||||
libfuzzer_oom = ["libfuzzer"]
|
libfuzzer_oom = ["libfuzzer"]
|
||||||
sanitizers_flags = []
|
sanitizers_flags = []
|
||||||
pointer_maps = []
|
pointer_maps = []
|
||||||
sancov_pcguard_edges = []
|
sancov_pcguard_edges = ["coverage"]
|
||||||
sancov_pcguard_hitcounts = []
|
sancov_pcguard_hitcounts = ["coverage"]
|
||||||
sancov_value_profile = []
|
sancov_value_profile = ["common"]
|
||||||
sancov_8bit = []
|
sancov_8bit = []
|
||||||
sancov_cmplog = [] # Defines cmp and __sanitizer_weak_hook functions. Use libfuzzer_interceptors to define interceptors (only compatible with Linux)
|
sancov_cmplog = ["common"] # Defines cmp and __sanitizer_weak_hook functions. Use libfuzzer_interceptors to define interceptors (only compatible with Linux)
|
||||||
sancov_pcguard = ["sancov_pcguard_hitcounts"]
|
sancov_pcguard = ["sancov_pcguard_hitcounts"]
|
||||||
sanitizer_interfaces = []
|
sanitizer_interfaces = []
|
||||||
clippy = [] # Ignore compiler warnings during clippy
|
clippy = [] # Ignore compiler warnings during clippy
|
||||||
observers = ["meminterval", "ahash"]
|
observers = ["meminterval", "ahash"]
|
||||||
|
common = [] # Compile common C code defining sanitizer options and cross-platform intrinsics
|
||||||
|
coverage = ["common"] # Compile C code definining coverage maps
|
||||||
|
cmplog = ["common"] # Compile C code defining cmp log maps
|
||||||
|
forkserver = ["common"] # Compile C code for forkserver support
|
||||||
|
windows_asan = ["common"] # Compile C code for ASAN on Windows
|
||||||
whole_archive = [] # use +whole-archive to ensure the presence of weak symbols
|
whole_archive = [] # use +whole-archive to ensure the presence of weak symbols
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
use std::{env, fs::File, io::Write, path::Path};
|
use std::{env, fs::File, io::Write, path::Path};
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
#[rustversion::not(nightly)]
|
|
||||||
compile_error!("Must use a nightly release with whole_archive!");
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
@ -68,6 +64,21 @@ fn main() {
|
|||||||
println!("cargo:rerun-if-env-changed=LIBAFL_CMPLOG_MAP_H");
|
println!("cargo:rerun-if-env-changed=LIBAFL_CMPLOG_MAP_H");
|
||||||
println!("cargo:rerun-if-env-changed=LIBAFL_ACCOUNTING_MAP_SIZE");
|
println!("cargo:rerun-if-env-changed=LIBAFL_ACCOUNTING_MAP_SIZE");
|
||||||
|
|
||||||
|
#[cfg(feature = "common")]
|
||||||
|
{
|
||||||
|
println!("cargo:rerun-if-changed=src/common.h");
|
||||||
|
println!("cargo:rerun-if-changed=src/common.c");
|
||||||
|
|
||||||
|
let mut common = cc::Build::new();
|
||||||
|
|
||||||
|
#[cfg(feature = "sanitizers_flags")]
|
||||||
|
{
|
||||||
|
common.define("DEFAULT_SANITIZERS_OPTIONS", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
common.file(src_dir.join("common.c")).compile("common");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "sancov_value_profile", feature = "sancov_cmplog"))]
|
#[cfg(any(feature = "sancov_value_profile", feature = "sancov_cmplog"))]
|
||||||
{
|
{
|
||||||
println!("cargo:rerun-if-changed=src/sancov_cmp.c");
|
println!("cargo:rerun-if-changed=src/sancov_cmp.c");
|
||||||
@ -76,10 +87,6 @@ fn main() {
|
|||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
sancov_cmp.flag("-Wno-sign-compare");
|
sancov_cmp.flag("-Wno-sign-compare");
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
sancov_cmp.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "sancov_value_profile")]
|
#[cfg(feature = "sancov_value_profile")]
|
||||||
{
|
{
|
||||||
@ -133,37 +140,91 @@ fn main() {
|
|||||||
let mut libfuzzer = cc::Build::new();
|
let mut libfuzzer = cc::Build::new();
|
||||||
libfuzzer.file(src_dir.join("libfuzzer.c"));
|
libfuzzer.file(src_dir.join("libfuzzer.c"));
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
libfuzzer.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "libfuzzer_no_link_main")]
|
#[cfg(feature = "libfuzzer_no_link_main")]
|
||||||
libfuzzer.define("FUZZER_NO_LINK_MAIN", "1");
|
libfuzzer.define("FUZZER_NO_LINK_MAIN", "1");
|
||||||
#[cfg(feature = "libfuzzer_define_run_driver")]
|
#[cfg(feature = "libfuzzer_define_run_driver")]
|
||||||
libfuzzer.define("FUZZER_DEFINE_RUN_DRIVER", "1");
|
libfuzzer.define("FUZZER_DEFINE_RUN_DRIVER", "1");
|
||||||
|
|
||||||
libfuzzer.compile("libfuzzer");
|
libfuzzer.compile("libfuzzer");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "libfuzzer_interceptors")]
|
#[cfg(feature = "coverage")]
|
||||||
{
|
{
|
||||||
println!("cargo:rerun-if-changed=src/libfuzzer/FuzzerInterceptors.cpp");
|
println!("cargo:rerun-if-changed=src/coverage.c");
|
||||||
|
|
||||||
let mut interceptors = cc::Build::new();
|
cc::Build::new()
|
||||||
interceptors.file(src_dir.join("libfuzzer/FuzzerInterceptors.cpp"));
|
.file(src_dir.join("coverage.c"))
|
||||||
|
.define("EDGES_MAP_SIZE", Some(&*format!("{edges_map_size}")))
|
||||||
|
.define("ACCOUNTING_MAP_SIZE", Some(&*format!("{acc_map_size}")))
|
||||||
|
.compile("coverage");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
#[cfg(feature = "cmplog")]
|
||||||
{
|
{
|
||||||
interceptors.link_lib_modifier("+whole-archive");
|
println!("cargo:rerun-if-changed=src/cmplog.h");
|
||||||
|
println!("cargo:rerun-if-changed=src/cmplog.c");
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
cc::Build::new()
|
||||||
|
.flag("-Wno-pointer-sign") // UNIX ONLY FLAGS
|
||||||
|
.flag("-Wno-sign-compare")
|
||||||
|
.define("CMP_MAP_SIZE", Some(&*format!("{cmp_map_size}")))
|
||||||
|
.define(
|
||||||
|
"AFLPP_CMPLOG_MAP_W",
|
||||||
|
Some(&*format!("{aflpp_cmplog_map_w}")),
|
||||||
|
)
|
||||||
|
.define(
|
||||||
|
"AFLPP_CMPLOG_MAP_H",
|
||||||
|
Some(&*format!("{aflpp_cmplog_map_h}")),
|
||||||
|
)
|
||||||
|
.define("CMPLOG_MAP_W", Some(&*format!("{cmplog_map_w}")))
|
||||||
|
.define("CMPLOG_MAP_H", Some(&*format!("{cmplog_map_h}")))
|
||||||
|
.file(src_dir.join("cmplog.c"))
|
||||||
|
.compile("cmplog");
|
||||||
}
|
}
|
||||||
|
|
||||||
interceptors.cpp(true).compile("interceptors");
|
#[cfg(not(unix))]
|
||||||
|
{
|
||||||
|
cc::Build::new()
|
||||||
|
.define("CMP_MAP_SIZE", Some(&*format!("{cmp_map_size}")))
|
||||||
|
.define(
|
||||||
|
"AFLPP_CMPLOG_MAP_W",
|
||||||
|
Some(&*format!("{aflpp_cmplog_map_w}")),
|
||||||
|
)
|
||||||
|
.define(
|
||||||
|
"AFLPP_CMPLOG_MAP_H",
|
||||||
|
Some(&*format!("{aflpp_cmplog_map_h}")),
|
||||||
|
)
|
||||||
|
.define("CMPLOG_MAP_W", Some(&*format!("{cmplog_map_w}")))
|
||||||
|
.define("CMPLOG_MAP_H", Some(&*format!("{cmplog_map_h}")))
|
||||||
|
.file(src_dir.join("cmplog.c"))
|
||||||
|
.compile("cmplog");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/common.h");
|
#[cfg(feature = "forkserver")]
|
||||||
println!("cargo:rerun-if-changed=src/common.c");
|
{
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
println!("cargo:rerun-if-changed=src/forkserver.c");
|
||||||
|
|
||||||
|
cc::Build::new()
|
||||||
|
.file(src_dir.join("forkserver.c"))
|
||||||
|
.compile("forkserver");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "windows_asan", windows))]
|
||||||
|
{
|
||||||
|
println!("cargo:rerun-if-changed=src/windows_asan.c");
|
||||||
|
|
||||||
|
cc::Build::new()
|
||||||
|
.file(src_dir.join("windows_asan.c"))
|
||||||
|
.compile("windows_asan");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Sanitizer interfaces doesn't require common
|
||||||
#[cfg(feature = "sanitizer_interfaces")]
|
#[cfg(feature = "sanitizer_interfaces")]
|
||||||
if env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "64" {
|
if env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "64" {
|
||||||
println!("cargo:rerun-if-changed=src/sanitizer_interfaces.h");
|
println!("cargo:rerun-if-changed=src/sanitizer_interfaces.h");
|
||||||
@ -185,99 +246,6 @@ fn main() {
|
|||||||
write!(file, "").unwrap();
|
write!(file, "").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut common = cc::Build::new();
|
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
common.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "sanitizers_flags")]
|
|
||||||
{
|
|
||||||
common.define("DEFAULT_SANITIZERS_OPTIONS", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
common.file(src_dir.join("common.c")).compile("common");
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/coverage.c");
|
|
||||||
|
|
||||||
let mut coverage = cc::Build::new();
|
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
coverage.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
coverage
|
|
||||||
.file(src_dir.join("coverage.c"))
|
|
||||||
.define("EDGES_MAP_SIZE", Some(&*format!("{edges_map_size}")))
|
|
||||||
.define("ACCOUNTING_MAP_SIZE", Some(&*format!("{acc_map_size}")))
|
|
||||||
.compile("coverage");
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/cmplog.h");
|
|
||||||
println!("cargo:rerun-if-changed=src/cmplog.c");
|
|
||||||
|
|
||||||
let mut cmplog = cc::Build::new();
|
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
cmplog.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
cmplog
|
|
||||||
.flag("-Wno-pointer-sign") // UNIX ONLY FLAGS
|
|
||||||
.flag("-Wno-sign-compare");
|
|
||||||
}
|
|
||||||
|
|
||||||
cmplog
|
|
||||||
.define("CMP_MAP_SIZE", Some(&*format!("{cmp_map_size}")))
|
|
||||||
.define(
|
|
||||||
"AFLPP_CMPLOG_MAP_W",
|
|
||||||
Some(&*format!("{aflpp_cmplog_map_w}")),
|
|
||||||
)
|
|
||||||
.define(
|
|
||||||
"AFLPP_CMPLOG_MAP_H",
|
|
||||||
Some(&*format!("{aflpp_cmplog_map_h}")),
|
|
||||||
)
|
|
||||||
.define("CMPLOG_MAP_W", Some(&*format!("{cmplog_map_w}")))
|
|
||||||
.define("CMPLOG_MAP_H", Some(&*format!("{cmplog_map_h}")))
|
|
||||||
.file(src_dir.join("cmplog.c"))
|
|
||||||
.compile("cmplog");
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
println!("cargo:rerun-if-changed=src/forkserver.c");
|
|
||||||
|
|
||||||
let mut forkserver = cc::Build::new();
|
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
forkserver.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
forkserver
|
|
||||||
.file(src_dir.join("forkserver.c"))
|
|
||||||
.compile("forkserver");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
println!("cargo:rerun-if-changed=src/windows_asan.c");
|
|
||||||
|
|
||||||
let mut winasan = cc::Build::new();
|
|
||||||
|
|
||||||
#[cfg(feature = "whole_archive")]
|
|
||||||
{
|
|
||||||
winasan.link_lib_modifier("+whole-archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
winasan
|
|
||||||
.file(src_dir.join("windows_asan.c"))
|
|
||||||
.compile("windows_asan");
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("cargo:rustc-link-search=native={}", &out_dir);
|
println!("cargo:rustc-link-search=native={}", &out_dir);
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
@ -46,6 +46,7 @@ pub const AFL_CMP_TYPE_RTN: u32 = 2;
|
|||||||
|
|
||||||
// EXTERNS, GLOBALS
|
// EXTERNS, GLOBALS
|
||||||
|
|
||||||
|
#[cfg(feature = "cmplog")]
|
||||||
// void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2)
|
// void __libafl_targets_cmplog_instructions(uintptr_t k, uint8_t shape, uint64_t arg1, uint64_t arg2)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/// Logs an instruction for feedback during fuzzing
|
/// Logs an instruction for feedback during fuzzing
|
||||||
@ -58,6 +59,7 @@ extern "C" {
|
|||||||
pub static mut libafl_cmplog_map_ptr: *mut CmpLogMap;
|
pub static mut libafl_cmplog_map_ptr: *mut CmpLogMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "cmplog")]
|
||||||
pub use libafl_cmplog_map_ptr as CMPLOG_MAP_PTR;
|
pub use libafl_cmplog_map_ptr as CMPLOG_MAP_PTR;
|
||||||
|
|
||||||
/// Value indicating if cmplog is enabled.
|
/// Value indicating if cmplog is enabled.
|
||||||
|
@ -14,8 +14,9 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{ownedref::OwnedMutPtr, Named};
|
use libafl_bolts::{ownedref::OwnedMutPtr, Named};
|
||||||
|
|
||||||
use crate::cmps::{libafl_cmplog_map_ptr, CmpLogMap, CMPLOG_ENABLED};
|
#[cfg(feature = "cmplog")]
|
||||||
|
use crate::cmps::libafl_cmplog_map_ptr;
|
||||||
|
use crate::cmps::{CmpLogMap, CMPLOG_ENABLED};
|
||||||
/// A [`CmpObserver`] observer for `CmpLog`
|
/// A [`CmpObserver`] observer for `CmpLog`
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CmpLogObserver {
|
pub struct CmpLogObserver {
|
||||||
@ -98,6 +99,7 @@ impl CmpLogObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "cmplog")]
|
||||||
/// Creates a new [`CmpLogObserver`] with the given name from the default cmplog map
|
/// Creates a new [`CmpLogObserver`] with the given name from the default cmplog map
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(name: &'static str, add_meta: bool) -> Self {
|
pub fn new(name: &'static str, add_meta: bool) -> Self {
|
||||||
|
@ -100,7 +100,9 @@ pub mod sancov_8bit;
|
|||||||
#[cfg(feature = "sancov_8bit")]
|
#[cfg(feature = "sancov_8bit")]
|
||||||
pub use sancov_8bit::*;
|
pub use sancov_8bit::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "coverage")]
|
||||||
pub mod coverage;
|
pub mod coverage;
|
||||||
|
#[cfg(feature = "coverage")]
|
||||||
pub use coverage::*;
|
pub use coverage::*;
|
||||||
|
|
||||||
pub mod value_profile;
|
pub mod value_profile;
|
||||||
@ -113,12 +115,12 @@ pub use cmps::*;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod drcov;
|
pub mod drcov;
|
||||||
|
|
||||||
#[cfg(all(windows, feature = "std"))]
|
#[cfg(all(windows, feature = "std", feture = "windows_asan"))]
|
||||||
pub mod windows_asan;
|
pub mod windows_asan;
|
||||||
#[cfg(all(windows, feature = "std"))]
|
#[cfg(all(windows, feature = "std", feture = "windows_asan"))]
|
||||||
pub use windows_asan::*;
|
pub use windows_asan::*;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(all(unix, feature = "forkserver"))]
|
||||||
pub mod forkserver;
|
pub mod forkserver;
|
||||||
#[cfg(unix)]
|
#[cfg(all(unix, feature = "forkserver"))]
|
||||||
pub use forkserver::*;
|
pub use forkserver::*;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user