diff --git a/fuzzers/libafl_atheris/Cargo.toml b/fuzzers/libafl_atheris/Cargo.toml index 2fc001fbbc..93d4229378 100644 --- a/fuzzers/libafl_atheris/Cargo.toml +++ b/fuzzers/libafl_atheris/Cargo.toml @@ -21,7 +21,7 @@ which = "4.4" [dependencies] libafl = { path = "../../libafl/" } libafl_bolts = { path = "../../libafl_bolts/" } -libafl_targets = { path = "../../libafl_targets/", features = ["pointer_maps", "sancov_cmplog", "libfuzzer"] } +libafl_targets = { path = "../../libafl_targets/", features = ["pointer_maps", "sancov_cmplog", "libfuzzer", "sancov_8bit"] } clap = { version = "4.0", features = ["default"] } [lib] diff --git a/fuzzers/libafl_atheris/src/lib.rs b/fuzzers/libafl_atheris/src/lib.rs index e7650c8c47..7209ec1589 100644 --- a/fuzzers/libafl_atheris/src/lib.rs +++ b/fuzzers/libafl_atheris/src/lib.rs @@ -25,7 +25,7 @@ use libafl::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::{I2SRandReplace, Tokens}, }, - observers::{HitcountsMapObserver, TimeObserver}, + observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::{StdMutationalStage, TracingStage}, state::{HasCorpus, HasMetadata, StdState}, @@ -39,63 +39,7 @@ use libafl_bolts::{ tuples::{tuple_list, Merge}, AsSlice, }; -use libafl_targets::{ - CmpLogObserver, __sanitizer_cov_trace_cmp1, __sanitizer_cov_trace_cmp2, - __sanitizer_cov_trace_cmp4, __sanitizer_cov_trace_cmp8, std_edges_map_observer, EDGES_MAP_PTR, - MAX_EDGES_NUM, -}; - -/// Set up our coverage map. -#[no_mangle] -pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) { - unsafe { - EDGES_MAP_PTR = start; - MAX_EDGES_NUM = (stop as usize - start as usize) / 8; - } -} - -/// `pcs` tables seem to be unused by `Atheris`, so we can ignore this setup function, -/// but the symbol is still being called and, hence, required. -#[no_mangle] -pub extern "C" fn __sanitizer_cov_pcs_init(_pcs_beg: *mut u8, _pcs_end: *mut u8) { - // noop -} - -/// Allow the python code to use `cmplog`. -/// This is a PoC implementation and could be improved. -/// For example, it only takes up to 8 bytes into consideration. -#[no_mangle] -pub extern "C" fn __sanitizer_weak_hook_memcmp( - _caller_pc: *const c_void, - s1: *const c_void, - s2: *const c_void, - n: usize, - _result: c_int, -) { - unsafe { - let s1 = slice::from_raw_parts(s1.cast::(), n); - let s2 = slice::from_raw_parts(s2.cast::(), n); - match n { - 0 => (), - 1 => __sanitizer_cov_trace_cmp1( - u8::from_ne_bytes(s1.try_into().unwrap()), - u8::from_ne_bytes(s2.try_into().unwrap()), - ), - 2..=3 => __sanitizer_cov_trace_cmp2( - u16::from_ne_bytes(s1.try_into().unwrap()), - u16::from_ne_bytes(s2.try_into().unwrap()), - ), - 4..=7 => __sanitizer_cov_trace_cmp4( - u32::from_ne_bytes(s1.try_into().unwrap()), - u32::from_ne_bytes(s2.try_into().unwrap()), - ), - _ => __sanitizer_cov_trace_cmp8( - u64::from_ne_bytes(s1.try_into().unwrap()), - u64::from_ne_bytes(s2.try_into().unwrap()), - ), - } - } -} +use libafl_targets::{extra_counters, std_edges_map_observer, CmpLogObserver}; /// It's called by Atheris after the fuzzer has been initialized. /// The main entrypoint to our fuzzer, which will be called by `Atheris` when fuzzing starts. @@ -115,11 +59,6 @@ pub extern "C" fn LLVMFuzzerRunDriver( assert!(harness_fn.is_some(), "No harness callback provided"); let harness_fn = harness_fn.unwrap(); - assert!( - !unsafe { EDGES_MAP_PTR.is_null() }, - "Edges map was never initialized - __sanitizer_cov_8bit_counters_init never got called" - ); - println!("Args: {:?}", std::env::args()); let matches = Command::new("libafl_atheris") @@ -156,10 +95,7 @@ pub extern "C" fn LLVMFuzzerRunDriver( .get_matches(); let workdir = env::current_dir().unwrap(); - println!( - "Workdir: {:?}", - env::current_dir().unwrap().to_string_lossy().to_string() - ); + println!("{}", env::current_dir().unwrap().to_string_lossy().to_string()); let cores = Cores::from_cmdline(matches.get_one::("cores").unwrap()) .expect("No valid core count given!"); @@ -195,7 +131,13 @@ pub extern "C" fn LLVMFuzzerRunDriver( let mut run_client = |state: Option<_>, mut mgr, _core_id| { // Create an observation channel using the coverage map - let edges_observer = unsafe { HitcountsMapObserver::new(std_edges_map_observer("edges")) }; + let edges = unsafe { extra_counters() }; + println!("edges: {:?}", edges); + let edges_observer; + edges_observer = HitcountsMapObserver::new(StdMapObserver::from_mut_slice( + "edges", + edges.into_iter().next().unwrap(), + )); // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); @@ -318,7 +260,7 @@ pub extern "C" fn LLVMFuzzerRunDriver( } else { println!("Loading from {:?}", &input_dirs); // Load from disk - // we used _forced since some Atheris testcases don't touch the map at all, hence, wolud not load any data. + // we used _forced since some Atheris testcases don't touch the map at all, hence, would not load any data. state .load_initial_inputs_forced(&mut fuzzer, &mut executor, &mut mgr, &input_dirs) .unwrap_or_else(|_| { @@ -341,8 +283,8 @@ pub extern "C" fn LLVMFuzzerRunDriver( .cores(&cores) .broker_port(broker_port) .remote_broker_addr(remote_broker_addr) - // remove this comment to sience the target. - //.stdout_file(Some("/dev/null")) + // remove this comment to silence the target. + // .stdout_file(Some("/dev/null")) .build() .launch() {