Fix missing -use_value_profile flag in libafl_libfuzzer (#2363)
* Add -use_value_profile to libafl_libfuzzer * clippy
This commit is contained in:
parent
d7b5d55408
commit
2356ba5754
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@ vendor
|
||||
*.bin
|
||||
*.dll
|
||||
*.exe
|
||||
*.dylib
|
||||
*.dSYM
|
||||
*.obj
|
||||
|
||||
|
@ -33,7 +33,7 @@ crate-type = ["staticlib", "rlib"]
|
||||
[dependencies]
|
||||
libafl = { path = "../../libafl", default-features = false, features = ["std", "derive", "llmp_compression", "rand_trait", "regex", "errors_backtrace", "serdeany_autoreg", "tui_monitor", "unicode"] }
|
||||
libafl_bolts = { path = "../../libafl_bolts", default-features = false, features = ["std", "derive", "llmp_compression", "rand_trait", "serdeany_autoreg", "errors_backtrace"] }
|
||||
libafl_targets = { path = "../../libafl_targets", features = ["sancov_8bit", "sancov_cmplog", "sancov_pcguard", "libfuzzer", "libfuzzer_oom", "libfuzzer_define_run_driver", "libfuzzer_interceptors", "sanitizers_flags", "whole_archive", "sanitizer_interfaces"] }
|
||||
libafl_targets = { path = "../../libafl_targets", features = ["sancov_8bit", "sancov_cmplog", "sancov_value_profile", "sancov_pcguard", "libfuzzer", "libfuzzer_oom", "libfuzzer_define_run_driver", "libfuzzer_interceptors", "sanitizers_flags", "whole_archive", "sanitizer_interfaces"] }
|
||||
|
||||
ahash = { version = "0.8.3", default-features = false }
|
||||
libc = "0.2.1"
|
||||
|
@ -17,6 +17,15 @@ if ! cargo +nightly --version >& /dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cargo +nightly build --profile "$profile"
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# MacOS and iOS
|
||||
"${CXX:-clang++}" -dynamiclib -Wl,-force_load target/release/libafl_libfuzzer_runtime.a \
|
||||
-Wl,-U,_LLVMFuzzerInitialize -Wl,-U,_LLVMFuzzerCustomMutator -Wl,-U,_LLVMFuzzerCustomCrossOver -Wl,-U,_libafl_main \
|
||||
-o libafl_libfuzzer_runtime.dylib
|
||||
else
|
||||
# Linux and *BSD
|
||||
RUSTC_BIN="$(cargo +nightly rustc -Zunstable-options --print target-libdir)/../bin"
|
||||
RUST_LLD="${RUSTC_BIN}/rust-lld"
|
||||
RUST_AR="${RUSTC_BIN}/llvm-ar"
|
||||
@ -26,8 +35,6 @@ if ! [ -f "${RUST_LLD}" ] && [ -f "${RUST_AR}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cargo +nightly build --profile "$profile"
|
||||
|
||||
tmpdir=""
|
||||
|
||||
cleanup() {
|
||||
@ -42,3 +49,5 @@ tmpdir="$(mktemp -d)"
|
||||
|
||||
echo "Done! Wrote the runtime to \`${SCRIPT_DIR}/libFuzzer.a'"
|
||||
cleanup
|
||||
fi
|
||||
|
||||
|
@ -139,7 +139,7 @@ impl CustomMutationStatus {
|
||||
}
|
||||
|
||||
macro_rules! fuzz_with {
|
||||
($options:ident, $harness:ident, $operation:expr, $and_then:expr, $edge_maker:expr) => {{
|
||||
($options:ident, $harness:ident, $operation:expr, $and_then:expr, $edge_maker:expr, $extra_feedback:expr, $extra_obsv:expr) => {{
|
||||
use libafl_bolts::{
|
||||
rands::StdRand,
|
||||
tuples::{Merge, tuple_list},
|
||||
@ -169,7 +169,7 @@ macro_rules! fuzz_with {
|
||||
state::{HasCorpus, StdState},
|
||||
StdFuzzer,
|
||||
};
|
||||
use libafl_targets::{CmpLogObserver, LLVMCustomMutator, OomFeedback, OomObserver};
|
||||
use libafl_targets::{CmpLogObserver, LLVMCustomMutator, OomFeedback, OomObserver, CMP_MAP};
|
||||
use rand::{thread_rng, RngCore};
|
||||
use std::{env::temp_dir, fs::create_dir, path::PathBuf};
|
||||
|
||||
@ -203,6 +203,9 @@ macro_rules! fuzz_with {
|
||||
// Create the Cmp observer
|
||||
let cmplog_observer = CmpLogObserver::new("cmplog", true);
|
||||
|
||||
// Create an observer using the cmp map for value profile
|
||||
let value_profile_observer = unsafe { StdMapObserver::from_mut_ptr("cmps", CMP_MAP.as_mut_ptr(), CMP_MAP.len()) };
|
||||
|
||||
// Create a stacktrace observer
|
||||
let backtrace_observer = BacktraceObserver::owned(
|
||||
"BacktraceObserver",
|
||||
@ -213,14 +216,27 @@ macro_rules! fuzz_with {
|
||||
let map_feedback = MaxMapFeedback::new(&edges_observer);
|
||||
let shrinking_map_feedback = ShrinkMapFeedback::new(&size_edges_observer);
|
||||
|
||||
// Value profile maximization feedback
|
||||
let value_profile_feedback = MaxMapFeedback::new(&value_profile_observer);
|
||||
|
||||
// Set up a generalization stage for grimoire
|
||||
let generalization = GeneralizationStage::new(&edges_observer);
|
||||
let generalization = IfStage::new(|_, _, _, _| Ok(grimoire.into()), tuple_list!(generalization));
|
||||
|
||||
let calibration = CalibrationStage::new(&map_feedback);
|
||||
|
||||
let add_extra_feedback = $extra_feedback;
|
||||
let coverage_feedback = add_extra_feedback(
|
||||
feedback_or!(
|
||||
map_feedback,
|
||||
feedback_and_fast!(ConstFeedback::new($options.shrink()), shrinking_map_feedback),
|
||||
// Time feedback, this one does not need a feedback state
|
||||
TimeFeedback::new(&time_observer)
|
||||
),
|
||||
value_profile_feedback
|
||||
);
|
||||
|
||||
// Feedback to rate the interestingness of an input
|
||||
// This one is composed by two Feedbacks in OR
|
||||
let mut feedback = feedback_and_fast!(
|
||||
feedback_not!(
|
||||
feedback_or_fast!(
|
||||
@ -230,12 +246,7 @@ macro_rules! fuzz_with {
|
||||
)
|
||||
),
|
||||
keep_observer,
|
||||
feedback_or!(
|
||||
map_feedback,
|
||||
feedback_and_fast!(ConstFeedback::new($options.shrink()), shrinking_map_feedback),
|
||||
// Time feedback, this one does not need a feedback state
|
||||
TimeFeedback::new(&time_observer)
|
||||
)
|
||||
coverage_feedback
|
||||
);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
@ -424,10 +435,16 @@ macro_rules! fuzz_with {
|
||||
|
||||
let mut tracing_harness = harness;
|
||||
|
||||
let add_extra_observer = $extra_obsv;
|
||||
let observers = add_extra_observer(
|
||||
tuple_list!(edges_observer, size_edges_observer, time_observer, backtrace_observer, oom_observer),
|
||||
value_profile_observer
|
||||
);
|
||||
|
||||
// Create the executor for an in-process function with one observer for edge coverage and one for the execution time
|
||||
let mut executor = InProcessExecutor::with_timeout(
|
||||
&mut harness,
|
||||
tuple_list!(edges_observer, size_edges_observer, time_observer, backtrace_observer, oom_observer),
|
||||
observers,
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
@ -466,7 +483,6 @@ macro_rules! fuzz_with {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Setup a tracing stage in which we log comparisons
|
||||
let tracing = IfStage::new(|_, _, _, _| Ok(!$options.skip_tracing()), (TracingStage::new(InProcessExecutor::new(
|
||||
&mut tracing_harness,
|
||||
@ -500,6 +516,21 @@ macro_rules! fuzz_with {
|
||||
$and_then(closure)
|
||||
}};
|
||||
|
||||
($options:ident, $harness:ident, $operation:expr, $and_then:expr, $edge_maker:expr) => {{
|
||||
if $options.use_value_profile() {
|
||||
fuzz_with!($options, $harness, $operation, $and_then, $edge_maker,
|
||||
|feedback, value_profile_feedback| {
|
||||
feedback_or!(feedback, value_profile_feedback)
|
||||
},
|
||||
|observers, value_profile_observer| {
|
||||
(value_profile_observer, observers) // Prepend the value profile observer in the tuple list
|
||||
}
|
||||
)
|
||||
} else {
|
||||
fuzz_with!($options, $harness, $operation, $and_then, $edge_maker, |feedback, _| feedback, |observers, _| observers)
|
||||
}
|
||||
}};
|
||||
|
||||
($options:ident, $harness:ident, $operation:expr, $and_then:expr) => {{
|
||||
use libafl::observers::{
|
||||
HitcountsIterableMapObserver, HitcountsMapObserver, MultiMapObserver, StdMapObserver,
|
||||
|
@ -107,6 +107,7 @@ pub struct LibfuzzerOptions {
|
||||
artifact_prefix: ArtifactPrefix,
|
||||
timeout: Duration,
|
||||
grimoire: Option<bool>,
|
||||
use_value_profile: bool,
|
||||
unicode: bool,
|
||||
forks: Option<usize>,
|
||||
dict: Option<Tokens>,
|
||||
@ -163,6 +164,10 @@ impl LibfuzzerOptions {
|
||||
self.grimoire
|
||||
}
|
||||
|
||||
pub fn use_value_profile(&self) -> bool {
|
||||
self.use_value_profile
|
||||
}
|
||||
|
||||
pub fn unicode(&self) -> bool {
|
||||
self.unicode
|
||||
}
|
||||
@ -235,6 +240,7 @@ struct LibfuzzerOptionsBuilder<'a> {
|
||||
artifact_prefix: Option<&'a str>,
|
||||
timeout: Option<Duration>,
|
||||
grimoire: Option<bool>,
|
||||
use_value_profile: Option<bool>,
|
||||
unicode: Option<bool>,
|
||||
forks: Option<usize>,
|
||||
dict: Option<&'a str>,
|
||||
@ -298,6 +304,9 @@ impl<'a> LibfuzzerOptionsBuilder<'a> {
|
||||
}
|
||||
}
|
||||
"grimoire" => self.grimoire = Some(parse_or_bail!(name, value, u64) > 0),
|
||||
"use_value_profile" => {
|
||||
self.use_value_profile = Some(parse_or_bail!(name, value, u64) > 0);
|
||||
}
|
||||
"unicode" => self.unicode = Some(parse_or_bail!(name, value, u64) > 0),
|
||||
"artifact_prefix" => {
|
||||
self.artifact_prefix = Some(value);
|
||||
@ -371,6 +380,7 @@ impl<'a> LibfuzzerOptionsBuilder<'a> {
|
||||
.unwrap_or_default(),
|
||||
timeout: self.timeout.unwrap_or(Duration::from_secs(1200)),
|
||||
grimoire: self.grimoire,
|
||||
use_value_profile: self.use_value_profile.unwrap_or(false),
|
||||
unicode: self.unicode.unwrap_or(true),
|
||||
forks: self.forks,
|
||||
dict: self.dict.map(|path| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user