Make harness function take mut ref (#1338)
* Change executor trait to allow \&mut Input * Add mut inprocess executor * Add mut inprocess executor * Format and fix clippy errors * Fix more clippy errors * Revert accidental refactoring of InMemoryCorpus * Add mut versions of all executors that can support it * Do not persist possible testcase mutation in stages, shadow/differential executors, or corpus minimization * Fix missing imports * Fix executor type for missed qemu items * Add re-exports for mut executors * Use InProcessForkExecutorMut in QemuForkExecutorMut * Update BytesInput harnesses to take mutable references * Update other-input-type-taking harnesses to take mut references * Clippy fixes * Feature gate TryFromIntError import * Fix missed harness input type in baby_fuzzer * Fix additional clippy issues * Fix unnecessary hashes on string literal * Even MORE clippy fixes * Fix one more clippy issue --------- Co-authored-by: Dongjia "toka" Zhang <tokazerkje@outlook.com>
This commit is contained in:
parent
52ab8c02d6
commit
fe6daecf0b
@ -6,7 +6,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
if buf.len() > 0 && buf[0] == 'a' as u8 {
|
if buf.len() > 0 && buf[0] == 'a' as u8 {
|
||||||
|
@ -17,7 +17,7 @@ use std::path::PathBuf;
|
|||||||
/* ANCHOR_END: use */
|
/* ANCHOR_END: use */
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
if buf.len() > 0 && buf[0] == 'a' as u8 {
|
if buf.len() > 0 && buf[0] == 'a' as u8 {
|
||||||
|
@ -28,7 +28,7 @@ fn signals_set(idx: usize) {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0); // set SIGNALS[0]
|
signals_set(0); // set SIGNALS[0]
|
||||||
|
@ -29,7 +29,7 @@ fn signals_set(idx: usize) {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0); // set SIGNALS[0]
|
signals_set(0); // set SIGNALS[0]
|
||||||
|
@ -34,7 +34,7 @@ fn signals_set(idx: usize) {
|
|||||||
#[allow(clippy::similar_names, clippy::manual_assert)]
|
#[allow(clippy::similar_names, clippy::manual_assert)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -49,7 +49,7 @@ pub fn main() {
|
|||||||
let mut bytes = vec![];
|
let mut bytes = vec![];
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &GramatronInput| {
|
let mut harness = |input: &mut GramatronInput| {
|
||||||
input.unparse(&mut bytes);
|
input.unparse(&mut bytes);
|
||||||
unsafe {
|
unsafe {
|
||||||
println!(">>> {}", std::str::from_utf8_unchecked(&bytes));
|
println!(">>> {}", std::str::from_utf8_unchecked(&bytes));
|
||||||
|
@ -65,7 +65,7 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target_bytes = input.target_bytes();
|
let target_bytes = input.target_bytes();
|
||||||
let bytes = target_bytes.as_slice();
|
let bytes = target_bytes.as_slice();
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ fn signals_set(idx: usize) {
|
|||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
pub fn main() -> Result<(), Error> {
|
pub fn main() -> Result<(), Error> {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -38,7 +38,7 @@ pub fn main() {
|
|||||||
let mut bytes = vec![];
|
let mut bytes = vec![];
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &NautilusInput| {
|
let mut harness = |input: &mut NautilusInput| {
|
||||||
input.unparse(&context, &mut bytes);
|
input.unparse(&context, &mut bytes);
|
||||||
unsafe {
|
unsafe {
|
||||||
println!(">>> {}", std::str::from_utf8_unchecked(&bytes));
|
println!(">>> {}", std::str::from_utf8_unchecked(&bytes));
|
||||||
|
@ -67,7 +67,7 @@ use slicemap::{HitcountsMapObserver, EDGES};
|
|||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut first_harness = |input: &BytesInput| {
|
let mut first_harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
if unsafe { inspect_first(buf.as_ptr(), buf.len()) } {
|
if unsafe { inspect_first(buf.as_ptr(), buf.len()) } {
|
||||||
@ -76,7 +76,7 @@ pub fn main() {
|
|||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut second_harness = |input: &BytesInput| {
|
let mut second_harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
if unsafe { inspect_second(buf.as_ptr(), buf.len()) } {
|
if unsafe { inspect_second(buf.as_ptr(), buf.len()) } {
|
||||||
|
@ -57,7 +57,7 @@ pub fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &EncodedInput| {
|
let mut harness = |input: &mut EncodedInput| {
|
||||||
decoded_bytes.clear();
|
decoded_bytes.clear();
|
||||||
encoder_decoder.decode(input, &mut decoded_bytes).unwrap();
|
encoder_decoder.decode(input, &mut decoded_bytes).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -44,7 +44,7 @@ pub fn fuzz() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -37,7 +37,7 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -69,7 +69,7 @@ pub extern "C" fn external_current_millis() -> u64 {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -38,7 +38,7 @@ pub fn main() {
|
|||||||
let mut shmem_provider = StdShMemProvider::new().unwrap();
|
let mut shmem_provider = StdShMemProvider::new().unwrap();
|
||||||
unsafe { create_shmem_array() };
|
unsafe { create_shmem_array() };
|
||||||
let map_ptr = unsafe { get_ptr() };
|
let map_ptr = unsafe { get_ptr() };
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
unsafe { c_harness(buf.as_ptr()) }
|
unsafe { c_harness(buf.as_ptr()) }
|
||||||
|
@ -28,7 +28,7 @@ extern "C" {
|
|||||||
|
|
||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
unsafe { c_harness(buf.as_ptr()) }
|
unsafe { c_harness(buf.as_ptr()) }
|
||||||
|
@ -39,7 +39,7 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -32,7 +32,7 @@ fn signals_set(idx: usize) {
|
|||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
signals_set(0);
|
signals_set(0);
|
||||||
|
@ -55,7 +55,7 @@ pub unsafe fn lib(main: extern "C" fn(i32, *const *const u8, *const *const u8) -
|
|||||||
|
|
||||||
let options = parse_args();
|
let options = parse_args();
|
||||||
|
|
||||||
let mut frida_harness = |input: &BytesInput| {
|
let mut frida_harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
let len = buf.len().to_string();
|
let len = buf.len().to_string();
|
||||||
@ -87,7 +87,7 @@ pub unsafe fn lib(main: extern "C" fn(i32, *const *const u8, *const *const u8) -
|
|||||||
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
|
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
|
||||||
unsafe fn fuzz(
|
unsafe fn fuzz(
|
||||||
options: &FuzzerOptions,
|
options: &FuzzerOptions,
|
||||||
mut frida_harness: &dyn Fn(&BytesInput) -> ExitKind,
|
mut frida_harness: &dyn Fn(&mut BytesInput) -> ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
// 'While the stats are state, they are usually used in the broker - which is likely never restarted
|
||||||
let monitor = MultiMonitor::new(|s| println!("{s}"));
|
let monitor = MultiMonitor::new(|s| println!("{s}"));
|
||||||
|
@ -85,7 +85,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
|||||||
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
||||||
> = lib.get(options.harness_function.as_bytes()).unwrap();
|
> = lib.get(options.harness_function.as_bytes()).unwrap();
|
||||||
|
|
||||||
let mut frida_harness = |input: &BytesInput| {
|
let mut frida_harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
(target_func)(buf.as_ptr(), buf.len());
|
(target_func)(buf.as_ptr(), buf.len());
|
||||||
|
@ -82,7 +82,7 @@ unsafe fn fuzz(options: &FuzzerOptions) -> Result<(), Error> {
|
|||||||
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
||||||
> = lib.get(options.harness_function.as_bytes()).unwrap();
|
> = lib.get(options.harness_function.as_bytes()).unwrap();
|
||||||
|
|
||||||
let mut frida_harness = |input: &BytesInput| {
|
let mut frida_harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
(target_func)(buf.as_ptr(), buf.len());
|
(target_func)(buf.as_ptr(), buf.len());
|
||||||
|
@ -317,7 +317,7 @@ fn fuzz(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -305,7 +305,7 @@ fn fuzz(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
let mut len = buf.len();
|
let mut len = buf.len();
|
||||||
|
@ -317,7 +317,7 @@ fn fuzz(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
let mut len = buf.len();
|
let mut len = buf.len();
|
||||||
|
@ -384,7 +384,7 @@ fn fuzz_binary(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
@ -609,7 +609,7 @@ fn fuzz_text(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -249,7 +249,7 @@ pub fn LLVMFuzzerRunDriver(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
harness_fn(buf.as_ptr(), buf.len());
|
harness_fn(buf.as_ptr(), buf.len());
|
||||||
@ -269,7 +269,7 @@ pub fn LLVMFuzzerRunDriver(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Secondary harness due to mut ownership
|
// Secondary harness due to mut ownership
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
harness_fn(buf.as_ptr(), buf.len());
|
harness_fn(buf.as_ptr(), buf.len());
|
||||||
|
@ -133,7 +133,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -157,7 +157,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
#[cfg(feature = "crash")]
|
#[cfg(feature = "crash")]
|
||||||
|
@ -198,7 +198,7 @@ pub fn libafl_main() {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -230,7 +230,7 @@ pub fn libafl_main() {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -156,7 +156,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
#[cfg(feature = "crash")]
|
#[cfg(feature = "crash")]
|
||||||
|
@ -189,7 +189,7 @@ pub fn libafl_main() {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -194,7 +194,7 @@ pub fn libafl_main() {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -215,7 +215,7 @@ pub fn libafl_main() {
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -155,7 +155,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
#[cfg(feature = "crash")]
|
#[cfg(feature = "crash")]
|
||||||
|
@ -112,7 +112,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -115,7 +115,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -153,7 +153,7 @@ fn fuzz(
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -122,7 +122,7 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -135,7 +135,7 @@ pub fn libafl_main() {
|
|||||||
let mut bytes = vec![];
|
let mut bytes = vec![];
|
||||||
|
|
||||||
// The closure that we want to fuzz
|
// The closure that we want to fuzz
|
||||||
let mut harness = |input: &NautilusInput| {
|
let mut harness = |input: &mut NautilusInput| {
|
||||||
input.unparse(&context, &mut bytes);
|
input.unparse(&context, &mut bytes);
|
||||||
libfuzzer_test_one_input(&bytes);
|
libfuzzer_test_one_input(&bytes);
|
||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
|
@ -32,7 +32,7 @@ fn signals_set(idx: usize) {
|
|||||||
#[allow(clippy::similar_names)]
|
#[allow(clippy::similar_names)]
|
||||||
fn input_generator() {
|
fn input_generator() {
|
||||||
// The closure that produced the input for the generator
|
// The closure that produced the input for the generator
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
// The `yield_` switches execution context back to the loop in `main`.
|
// The `yield_` switches execution context back to the loop in `main`.
|
||||||
// When `resume` is called, we return to this function.
|
// When `resume` is called, we return to this function.
|
||||||
yield_(input);
|
yield_(input);
|
||||||
|
@ -203,7 +203,7 @@ pub fn fuzz() {
|
|||||||
let input_addr = emu.map_private(0, 4096, MmapPerms::ReadWrite).unwrap();
|
let input_addr = emu.map_private(0, 4096, MmapPerms::ReadWrite).unwrap();
|
||||||
println!("Placing input at {input_addr:#x}");
|
println!("Placing input at {input_addr:#x}");
|
||||||
|
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target
|
let buf = target
|
||||||
.as_slice()
|
.as_slice()
|
||||||
|
@ -210,7 +210,7 @@ pub fn fuzz() {
|
|||||||
let input_addr = emu.map_private(0, 4096, MmapPerms::ReadWrite).unwrap();
|
let input_addr = emu.map_private(0, 4096, MmapPerms::ReadWrite).unwrap();
|
||||||
println!("Placing input at {input_addr:#x}");
|
println!("Placing input at {input_addr:#x}");
|
||||||
|
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target
|
let buf = target
|
||||||
.as_slice()
|
.as_slice()
|
||||||
|
@ -99,7 +99,7 @@ pub fn fuzz() {
|
|||||||
let snap = emu.create_fast_snapshot(true);
|
let snap = emu.create_fast_snapshot(true);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let mut buf = target.as_slice();
|
let mut buf = target.as_slice();
|
||||||
let len = buf.len();
|
let len = buf.len();
|
||||||
|
@ -56,7 +56,7 @@ pub fn libafl_main() {
|
|||||||
/// The actual fuzzer
|
/// The actual fuzzer
|
||||||
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Result<(), Error> {
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &PacketData| {
|
let mut harness = |input: &mut PacketData| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
libfuzzer_test_one_input(buf);
|
libfuzzer_test_one_input(buf);
|
||||||
|
@ -54,11 +54,11 @@ pub fn dump_registers<W: Write>(
|
|||||||
writer: &mut BufWriter<W>,
|
writer: &mut BufWriter<W>,
|
||||||
ucontext: &ucontext_t,
|
ucontext: &ucontext_t,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
for reg in 0..31 {
|
for reg in 0..31_usize {
|
||||||
write!(
|
write!(
|
||||||
writer,
|
writer,
|
||||||
"x{:02}: 0x{:016x} ",
|
"x{:02}: 0x{:016x} ",
|
||||||
reg, ucontext.uc_mcontext.regs[reg as usize]
|
reg, ucontext.uc_mcontext.regs[reg]
|
||||||
)?;
|
)?;
|
||||||
if reg % 4 == 3 {
|
if reg % 4 == 3 {
|
||||||
writeln!(writer)?;
|
writeln!(writer)?;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
//! too.)
|
//! too.)
|
||||||
|
|
||||||
use alloc::{rc::Rc, string::ToString};
|
use alloc::{rc::Rc, string::ToString};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use core::num::TryFromIntError;
|
||||||
use core::{
|
use core::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
fmt::{self, Debug, Display},
|
fmt::{self, Debug, Display},
|
||||||
@ -1442,23 +1444,34 @@ impl<T: ShMem> std::io::Seek for ShMemCursor<T> {
|
|||||||
std::io::SeekFrom::Start(s) => s,
|
std::io::SeekFrom::Start(s) => s,
|
||||||
std::io::SeekFrom::End(offset) => {
|
std::io::SeekFrom::End(offset) => {
|
||||||
let map_len = self.inner.as_slice().len();
|
let map_len = self.inner.as_slice().len();
|
||||||
i64::try_from(map_len).unwrap();
|
let signed_pos: i64 = map_len.try_into().map_err(|e: TryFromIntError| {
|
||||||
let signed_pos = i64::try_from(map_len).unwrap();
|
std::io::Error::new(std::io::ErrorKind::Other, e)
|
||||||
let effective = signed_pos.checked_add(offset).unwrap();
|
})?;
|
||||||
|
let effective = signed_pos.checked_add(offset).ok_or_else(|| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, "Invalid offset")
|
||||||
|
})?;
|
||||||
assert!(effective >= 0);
|
assert!(effective >= 0);
|
||||||
effective.try_into().unwrap()
|
effective.try_into().map_err(|e: TryFromIntError| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, e)
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
std::io::SeekFrom::Current(offset) => {
|
std::io::SeekFrom::Current(offset) => {
|
||||||
let current_pos = self.pos;
|
let current_pos = self.pos;
|
||||||
i64::try_from(current_pos).unwrap();
|
let signed_pos: i64 = current_pos.try_into().map_err(|e: TryFromIntError| {
|
||||||
let signed_pos = i64::try_from(current_pos).unwrap();
|
std::io::Error::new(std::io::ErrorKind::Other, e)
|
||||||
let effective = signed_pos.checked_add(offset).unwrap();
|
})?;
|
||||||
|
let effective = signed_pos.checked_add(offset).ok_or_else(|| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, "Invalid offset")
|
||||||
|
})?;
|
||||||
assert!(effective >= 0);
|
assert!(effective >= 0);
|
||||||
effective.try_into().unwrap()
|
effective.try_into().map_err(|e: TryFromIntError| {
|
||||||
|
std::io::Error::new(std::io::ErrorKind::Other, e)
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
usize::try_from(effective_new_pos).unwrap();
|
self.pos = effective_new_pos
|
||||||
self.pos = effective_new_pos as usize;
|
.try_into()
|
||||||
|
.map_err(|e: TryFromIntError| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
||||||
Ok(effective_new_pos)
|
Ok(effective_new_pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ where
|
|||||||
|
|
||||||
// Execute the input; we cannot rely on the metadata already being present.
|
// Execute the input; we cannot rely on the metadata already being present.
|
||||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||||
let kind = executor.run_target(fuzzer, state, manager, &input)?;
|
let kind = executor.run_target(fuzzer, state, manager, &mut input.clone())?;
|
||||||
executor
|
executor
|
||||||
.observers_mut()
|
.observers_mut()
|
||||||
.post_exec_all(state, &input, &kind)?;
|
.post_exec_all(state, &input, &kind)?;
|
||||||
|
@ -1558,7 +1558,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
let mut harness = |_buf: &BytesInput| ExitKind::Ok;
|
let mut harness = |_buf: &mut BytesInput| ExitKind::Ok;
|
||||||
let mut executor = InProcessExecutor::new(
|
let mut executor = InProcessExecutor::new(
|
||||||
&mut harness,
|
&mut harness,
|
||||||
tuple_list!(),
|
tuple_list!(),
|
||||||
|
@ -52,7 +52,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let ret = self.primary.run_target(fuzzer, state, mgr, input);
|
let ret = self.primary.run_target(fuzzer, state, mgr, input);
|
||||||
self.primary.post_run_reset();
|
self.primary.post_run_reset();
|
||||||
|
@ -323,7 +323,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
use std::os::unix::prelude::ExitStatusExt;
|
use std::os::unix::prelude::ExitStatusExt;
|
||||||
|
|
||||||
@ -712,7 +712,7 @@ mod tests {
|
|||||||
&mut NopFuzzer::new(),
|
&mut NopFuzzer::new(),
|
||||||
&mut NopState::new(),
|
&mut NopState::new(),
|
||||||
&mut mgr,
|
&mut mgr,
|
||||||
&BytesInput::new(b"test".to_vec()),
|
&mut BytesInput::new(b"test".to_vec()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -740,7 +740,7 @@ mod tests {
|
|||||||
&mut NopFuzzer::new(),
|
&mut NopFuzzer::new(),
|
||||||
&mut NopState::new(),
|
&mut NopState::new(),
|
||||||
&mut mgr,
|
&mut mgr,
|
||||||
&BytesInput::new(b"test".to_vec()),
|
&mut BytesInput::new(b"test".to_vec()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
self.observers(); // update in advance
|
self.observers(); // update in advance
|
||||||
let observers = self.observers.get_mut();
|
let observers = self.observers.get_mut();
|
||||||
|
@ -429,7 +429,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let mut exit_kind = ExitKind::Ok;
|
let mut exit_kind = ExitKind::Ok;
|
||||||
|
|
||||||
@ -1091,7 +1091,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let mut exit_kind = ExitKind::Ok;
|
let mut exit_kind = ExitKind::Ok;
|
||||||
|
|
||||||
|
@ -56,22 +56,27 @@ use crate::{
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The process executor simply calls a target function, as mutable reference to a closure
|
/// [`InProcessExecutor`] calls a target function as a mutable reference to a closure with a
|
||||||
|
/// mutable reference to the input as an argument to allow the harness to mutate the input
|
||||||
pub type InProcessExecutor<'a, H, OT, S> = GenericInProcessExecutor<H, &'a mut H, OT, S>;
|
pub type InProcessExecutor<'a, H, OT, S> = GenericInProcessExecutor<H, &'a mut H, OT, S>;
|
||||||
|
|
||||||
/// The process executor simply calls a target function, as boxed `FnMut` trait object
|
/// [`OwnedInProcessExecutor`] calls a boxed target function as a mutable reference
|
||||||
|
/// to a closure with a mutable reference to the input as an argument to allow the
|
||||||
|
/// harness to mutate the input
|
||||||
pub type OwnedInProcessExecutor<OT, S> = GenericInProcessExecutor<
|
pub type OwnedInProcessExecutor<OT, S> = GenericInProcessExecutor<
|
||||||
dyn FnMut(&<S as UsesInput>::Input) -> ExitKind,
|
dyn FnMut(&mut <S as UsesInput>::Input) -> ExitKind,
|
||||||
Box<dyn FnMut(&<S as UsesInput>::Input) -> ExitKind>,
|
Box<dyn FnMut(&mut <S as UsesInput>::Input) -> ExitKind>,
|
||||||
OT,
|
OT,
|
||||||
S,
|
S,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// The inmem executor simply calls a target function, then returns afterwards.
|
/// The [`GenericInProcessExecutor`] calls a target function as a mutable reference
|
||||||
|
/// to a closure with a mutable reference to the input as an argument to allow the
|
||||||
|
/// harness to mutate the input, and returns afterwards
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct GenericInProcessExecutor<H, HB, OT, S>
|
pub struct GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -87,7 +92,7 @@ where
|
|||||||
|
|
||||||
impl<H, HB, OT, S> Debug for GenericInProcessExecutor<H, HB, OT, S>
|
impl<H, HB, OT, S> Debug for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -102,7 +107,7 @@ where
|
|||||||
|
|
||||||
impl<H, HB, OT, S> UsesState for GenericInProcessExecutor<H, HB, OT, S>
|
impl<H, HB, OT, S> UsesState for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -112,7 +117,7 @@ where
|
|||||||
|
|
||||||
impl<H, HB, OT, S> UsesObservers for GenericInProcessExecutor<H, HB, OT, S>
|
impl<H, HB, OT, S> UsesObservers for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -122,7 +127,7 @@ where
|
|||||||
|
|
||||||
impl<EM, H, HB, OT, S, Z> Executor<EM, Z> for GenericInProcessExecutor<H, HB, OT, S>
|
impl<EM, H, HB, OT, S, Z> Executor<EM, Z> for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -134,7 +139,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
self.handlers
|
self.handlers
|
||||||
.pre_run_target(self, fuzzer, state, mgr, input);
|
.pre_run_target(self, fuzzer, state, mgr, input);
|
||||||
@ -146,27 +151,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, HB, OT, S> HasObservers for GenericInProcessExecutor<H, HB, OT, S>
|
|
||||||
where
|
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
|
||||||
HB: BorrowMut<H>,
|
|
||||||
OT: ObserversTuple<S>,
|
|
||||||
S: UsesInput,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn observers(&self) -> &OT {
|
|
||||||
&self.observers
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn observers_mut(&mut self) -> &mut OT {
|
|
||||||
&mut self.observers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<H, HB, OT, S> GenericInProcessExecutor<H, HB, OT, S>
|
impl<H, HB, OT, S> GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&<S as UsesInput>::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut <S as UsesInput>::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions,
|
S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions,
|
||||||
@ -174,7 +161,8 @@ where
|
|||||||
/// Create a new in mem executor.
|
/// Create a new in mem executor.
|
||||||
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
/// Caution: crash and restart in one of them will lead to odd behavior if multiple are used,
|
||||||
/// depending on different corpus or state.
|
/// depending on different corpus or state.
|
||||||
/// * `harness_fn` - the harness, executing the function
|
/// * `harness_fn` - the harness, executing the function. The harness may also mutate the
|
||||||
|
/// input.
|
||||||
/// * `observers` - the observers observing the target during execution
|
/// * `observers` - the observers observing the target during execution
|
||||||
/// This may return an error on unix, if signal handler setup fails
|
/// This may return an error on unix, if signal handler setup fails
|
||||||
pub fn new<CF, EM, OF, Z>(
|
pub fn new<CF, EM, OF, Z>(
|
||||||
@ -243,6 +231,24 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<H, HB, OT, S> HasObservers for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
|
where
|
||||||
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
|
HB: BorrowMut<H>,
|
||||||
|
OT: ObserversTuple<S>,
|
||||||
|
S: UsesInput,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn observers(&self) -> &OT {
|
||||||
|
&self.observers
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn observers_mut(&mut self) -> &mut OT {
|
||||||
|
&mut self.observers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The struct has [`InProcessHandlers`].
|
/// The struct has [`InProcessHandlers`].
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub trait HasInProcessHandlers {
|
pub trait HasInProcessHandlers {
|
||||||
@ -253,7 +259,7 @@ pub trait HasInProcessHandlers {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
impl<H, HB, OT, S> HasInProcessHandlers for GenericInProcessExecutor<H, HB, OT, S>
|
impl<H, HB, OT, S> HasInProcessHandlers for GenericInProcessExecutor<H, HB, OT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&<S as UsesInput>::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut <S as UsesInput>::Input) -> ExitKind + ?Sized,
|
||||||
HB: BorrowMut<H>,
|
HB: BorrowMut<H>,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions,
|
S: HasSolutions + HasClientPerfMonitor + HasCorpus + HasExecutions,
|
||||||
@ -1584,10 +1590,12 @@ extern "C" {
|
|||||||
const ITIMER_REAL: libc::c_int = 0;
|
const ITIMER_REAL: libc::c_int = 0;
|
||||||
|
|
||||||
/// [`InProcessForkExecutor`] is an executor that forks the current process before each execution.
|
/// [`InProcessForkExecutor`] is an executor that forks the current process before each execution.
|
||||||
|
/// It is the same as [`InProcessForkExecutor`] except that it allows the harness input to be
|
||||||
|
/// mutated.
|
||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
pub struct InProcessForkExecutor<'a, H, OT, S, SP>
|
pub struct InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1603,7 +1611,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
pub struct TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
pub struct TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1622,7 +1630,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> Debug for InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> Debug for InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1638,7 +1646,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> Debug for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> Debug for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1667,7 +1675,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> UsesState for InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> UsesState for InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1678,7 +1686,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> UsesState for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> UsesState for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1690,7 +1698,7 @@ where
|
|||||||
impl<'a, EM, H, OT, S, SP, Z> Executor<EM, Z> for InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, EM, H, OT, S, SP, Z> Executor<EM, Z> for InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1703,7 +1711,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.shmem_provider.pre_fork()?;
|
self.shmem_provider.pre_fork()?;
|
||||||
@ -1758,7 +1766,7 @@ where
|
|||||||
impl<'a, EM, H, OT, S, SP, Z> Executor<EM, Z> for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, EM, H, OT, S, SP, Z> Executor<EM, Z> for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1771,7 +1779,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.shmem_provider.pre_fork()?;
|
self.shmem_provider.pre_fork()?;
|
||||||
@ -1860,7 +1868,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput + HasCorpus,
|
S: UsesInput + HasCorpus,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -1909,7 +1917,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
S: UsesInput + HasCorpus,
|
S: UsesInput + HasCorpus,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -2020,7 +2028,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> UsesObservers for InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> UsesObservers for InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -2031,7 +2039,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> UsesObservers for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> UsesObservers for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: ?Sized + FnMut(&S::Input) -> ExitKind,
|
H: ?Sized + FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -2042,7 +2050,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> HasObservers for InProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> HasObservers for InProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -2061,7 +2069,7 @@ where
|
|||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
impl<'a, H, OT, S, SP> HasObservers for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
impl<'a, H, OT, S, SP> HasObservers for TimeoutInProcessForkExecutor<'a, H, OT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind + ?Sized,
|
H: FnMut(&mut S::Input) -> ExitKind + ?Sized,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
SP: ShMemProvider,
|
SP: ShMemProvider,
|
||||||
@ -2189,7 +2197,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inmem_exec() {
|
fn test_inmem_exec() {
|
||||||
let mut harness = |_buf: &NopInput| ExitKind::Ok;
|
let mut harness = |_buf: &mut NopInput| ExitKind::Ok;
|
||||||
|
|
||||||
let mut in_process_executor = InProcessExecutor::<_, _, _> {
|
let mut in_process_executor = InProcessExecutor::<_, _, _> {
|
||||||
harness_fn: &mut harness,
|
harness_fn: &mut harness,
|
||||||
@ -2197,13 +2205,13 @@ mod tests {
|
|||||||
handlers: InProcessHandlers::nop(),
|
handlers: InProcessHandlers::nop(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
};
|
};
|
||||||
let input = NopInput {};
|
let mut input = NopInput {};
|
||||||
in_process_executor
|
in_process_executor
|
||||||
.run_target(
|
.run_target(
|
||||||
&mut NopFuzzer::new(),
|
&mut NopFuzzer::new(),
|
||||||
&mut NopState::new(),
|
&mut NopState::new(),
|
||||||
&mut NopEventManager::new(),
|
&mut NopEventManager::new(),
|
||||||
&input,
|
&mut input,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -2223,7 +2231,7 @@ mod tests {
|
|||||||
|
|
||||||
let provider = StdShMemProvider::new().unwrap();
|
let provider = StdShMemProvider::new().unwrap();
|
||||||
|
|
||||||
let mut harness = |_buf: &NopInput| ExitKind::Ok;
|
let mut harness = |_buf: &mut NopInput| ExitKind::Ok;
|
||||||
let mut in_process_fork_executor = InProcessForkExecutor::<_, (), _, _> {
|
let mut in_process_fork_executor = InProcessForkExecutor::<_, (), _, _> {
|
||||||
harness_fn: &mut harness,
|
harness_fn: &mut harness,
|
||||||
shmem_provider: provider,
|
shmem_provider: provider,
|
||||||
@ -2231,12 +2239,12 @@ mod tests {
|
|||||||
handlers: InChildProcessHandlers::nop(),
|
handlers: InChildProcessHandlers::nop(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
};
|
};
|
||||||
let input = NopInput {};
|
let mut input = NopInput {};
|
||||||
let mut fuzzer = NopFuzzer::new();
|
let mut fuzzer = NopFuzzer::new();
|
||||||
let mut state = NopState::new();
|
let mut state = NopState::new();
|
||||||
let mut mgr = SimpleEventManager::printing();
|
let mut mgr = SimpleEventManager::printing();
|
||||||
in_process_fork_executor
|
in_process_fork_executor
|
||||||
.run_target(&mut fuzzer, &mut state, &mut mgr, &input)
|
.run_target(&mut fuzzer, &mut state, &mut mgr, &mut input)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2278,7 +2286,7 @@ pub mod pybind {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: OwnedInProcessExecutor::new(
|
inner: OwnedInProcessExecutor::new(
|
||||||
Box::new(move |input: &BytesInput| {
|
Box::new(move |input: &mut BytesInput| {
|
||||||
Python::with_gil(|py| -> PyResult<()> {
|
Python::with_gil(|py| -> PyResult<()> {
|
||||||
let args = (PyBytes::new(py, input.bytes()),);
|
let args = (PyBytes::new(py, input.bytes()),);
|
||||||
harness.call1(py, args)?;
|
harness.call1(py, args)?;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
pub mod inprocess;
|
pub mod inprocess;
|
||||||
pub use inprocess::InProcessExecutor;
|
pub use inprocess::InProcessExecutor;
|
||||||
#[cfg(all(feature = "std", feature = "fork", unix))]
|
#[cfg(all(feature = "std", feature = "fork", unix))]
|
||||||
pub use inprocess::InProcessForkExecutor;
|
pub use inprocess::{InProcessForkExecutor, TimeoutInProcessForkExecutor};
|
||||||
|
|
||||||
pub mod differential;
|
pub mod differential;
|
||||||
pub use differential::DiffExecutor;
|
pub use differential::DiffExecutor;
|
||||||
@ -121,7 +121,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error>;
|
) -> Result<ExitKind, Error>;
|
||||||
|
|
||||||
/// Wraps this Executor with the given [`ObserversTuple`] to implement [`HasObservers`].
|
/// Wraps this Executor with the given [`ObserversTuple`] to implement [`HasObservers`].
|
||||||
@ -167,7 +167,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
if input.target_bytes().as_slice().is_empty() {
|
if input.target_bytes().as_slice().is_empty() {
|
||||||
Err(Error::empty("Input Empty"))
|
Err(Error::empty("Input Empty"))
|
||||||
@ -186,8 +186,8 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nop_executor() {
|
fn nop_executor() {
|
||||||
let empty_input = BytesInput::new(vec![]);
|
let mut empty_input = BytesInput::new(vec![]);
|
||||||
let nonempty_input = BytesInput::new(vec![1u8]);
|
let mut nonempty_input = BytesInput::new(vec![1u8]);
|
||||||
let mut executor = NopExecutor {
|
let mut executor = NopExecutor {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
};
|
};
|
||||||
@ -200,7 +200,7 @@ mod test {
|
|||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
&mut state,
|
&mut state,
|
||||||
&mut NopEventManager::new(),
|
&mut NopEventManager::new(),
|
||||||
&empty_input,
|
&mut empty_input,
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
executor
|
executor
|
||||||
@ -208,7 +208,7 @@ mod test {
|
|||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
&mut state,
|
&mut state,
|
||||||
&mut NopEventManager::new(),
|
&mut NopEventManager::new(),
|
||||||
&nonempty_input,
|
&mut nonempty_input,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -352,7 +352,7 @@ pub mod pybind {
|
|||||||
fuzzer: &mut PythonStdFuzzer,
|
fuzzer: &mut PythonStdFuzzer,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut PythonEventManager,
|
mgr: &mut PythonEventManager,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let ek = Python::with_gil(|py| -> PyResult<_> {
|
let ek = Python::with_gil(|py| -> PyResult<_> {
|
||||||
let ek: PythonExitKind = self
|
let ek: PythonExitKind = self
|
||||||
@ -475,7 +475,7 @@ pub mod pybind {
|
|||||||
fuzzer: &mut PythonStdFuzzer,
|
fuzzer: &mut PythonStdFuzzer,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut PythonEventManager,
|
mgr: &mut PythonEventManager,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unwrap_me_mut!(self.wrapper, e, { e.run_target(fuzzer, state, mgr, input) })
|
unwrap_me_mut!(self.wrapper, e, { e.run_target(fuzzer, state, mgr, input) })
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,10 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
self.executor.run_target(fuzzer, state, mgr, input)
|
let mut input = input.clone();
|
||||||
|
self.executor.run_target(fuzzer, state, mgr, &mut input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data = &mut GLOBAL_STATE;
|
let data = &mut GLOBAL_STATE;
|
||||||
@ -460,7 +460,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.batch_mode {
|
if self.batch_mode {
|
||||||
@ -533,7 +533,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
setitimer(ITIMER_REAL, &mut self.itimerval, null_mut());
|
setitimer(ITIMER_REAL, &mut self.itimerval, null_mut());
|
||||||
|
@ -28,7 +28,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
self.executor.run_target(fuzzer, state, mgr, input)
|
self.executor.run_target(fuzzer, state, mgr, input)
|
||||||
}
|
}
|
||||||
|
@ -456,14 +456,14 @@ where
|
|||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
input: <Self::State as UsesInput>::Input,
|
mut input: <Self::State as UsesInput>::Input,
|
||||||
send_events: bool,
|
send_events: bool,
|
||||||
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
|
) -> Result<(ExecuteInputResult, Option<CorpusId>), Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, Self> + HasObservers<Observers = OT, State = Self::State>,
|
E: Executor<EM, Self> + HasObservers<Observers = OT, State = Self::State>,
|
||||||
EM: EventFirer<State = Self::State>,
|
EM: EventFirer<State = Self::State>,
|
||||||
{
|
{
|
||||||
let exit_kind = self.execute_input(state, executor, manager, &input)?;
|
let exit_kind = self.execute_input(state, executor, manager, &mut input)?;
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
|
|
||||||
self.scheduler.on_evaluation(state, &input, observers)?;
|
self.scheduler.on_evaluation(state, &input, observers)?;
|
||||||
@ -501,9 +501,9 @@ where
|
|||||||
state: &mut CS::State,
|
state: &mut CS::State,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
manager: &mut EM,
|
manager: &mut EM,
|
||||||
input: <CS::State as UsesInput>::Input,
|
mut input: <CS::State as UsesInput>::Input,
|
||||||
) -> Result<CorpusId, Error> {
|
) -> Result<CorpusId, Error> {
|
||||||
let exit_kind = self.execute_input(state, executor, manager, &input)?;
|
let exit_kind = self.execute_input(state, executor, manager, &mut input)?;
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
// Always consider this to be "interesting"
|
// Always consider this to be "interesting"
|
||||||
|
|
||||||
@ -647,7 +647,7 @@ where
|
|||||||
state: &mut CS::State,
|
state: &mut CS::State,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
input: &<CS::State as UsesInput>::Input,
|
input: &mut <CS::State as UsesInput>::Input,
|
||||||
) -> Result<ExitKind, Error>
|
) -> Result<ExitKind, Error>
|
||||||
where
|
where
|
||||||
E: Executor<EM, Self> + HasObservers<Observers = OT, State = CS::State>,
|
E: Executor<EM, Self> + HasObservers<Observers = OT, State = CS::State>,
|
||||||
@ -686,7 +686,7 @@ where
|
|||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
input: &<Self::State as UsesInput>::Input,
|
input: &mut <Self::State as UsesInput>::Input,
|
||||||
) -> Result<ExitKind, Error>;
|
) -> Result<ExitKind, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,7 +705,7 @@ where
|
|||||||
state: &mut CS::State,
|
state: &mut CS::State,
|
||||||
executor: &mut E,
|
executor: &mut E,
|
||||||
event_mgr: &mut EM,
|
event_mgr: &mut EM,
|
||||||
input: &<CS::State as UsesInput>::Input,
|
input: &mut <CS::State as UsesInput>::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
start_timer!(state);
|
start_timer!(state);
|
||||||
executor.observers_mut().pre_exec_all(state, input)?;
|
executor.observers_mut().pre_exec_all(state, input)?;
|
||||||
|
@ -502,7 +502,7 @@ mod tests {
|
|||||||
let scheduler = RandScheduler::new();
|
let scheduler = RandScheduler::new();
|
||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
let mut harness = |_buf: &BytesInput| ExitKind::Ok;
|
let mut harness = |_buf: &mut BytesInput| ExitKind::Ok;
|
||||||
let mut executor = InProcessExecutor::new(
|
let mut executor = InProcessExecutor::new(
|
||||||
&mut harness,
|
&mut harness,
|
||||||
tuple_list!(),
|
tuple_list!(),
|
||||||
|
@ -1239,20 +1239,20 @@ impl CrossoverReplaceMutator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first and last diff position between the given vectors, stopping at the min len
|
/// Returns the first and last diff position between the given vectors, stopping at the min len
|
||||||
fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
|
fn locate_diffs(this: &[u8], other: &[u8]) -> Result<(i64, i64), Error> {
|
||||||
let mut first_diff: i64 = -1;
|
let mut first_diff: i64 = -1;
|
||||||
let mut last_diff: i64 = -1;
|
let mut last_diff: i64 = -1;
|
||||||
for (i, (this_el, other_el)) in this.iter().zip(other.iter()).enumerate() {
|
for (i, (this_el, other_el)) in this.iter().zip(other.iter()).enumerate() {
|
||||||
#[allow(clippy::cast_possible_wrap)]
|
#[allow(clippy::cast_possible_wrap)]
|
||||||
if this_el != other_el {
|
if this_el != other_el {
|
||||||
if first_diff < 0 {
|
if first_diff < 0 {
|
||||||
first_diff = i as i64;
|
first_diff = i.try_into()?;
|
||||||
}
|
}
|
||||||
last_diff = i as i64;
|
last_diff = i.try_into()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(first_diff, last_diff)
|
Ok((first_diff, last_diff))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Splice mutation for inputs with a bytes vector
|
/// Splice mutation for inputs with a bytes vector
|
||||||
@ -1285,7 +1285,7 @@ where
|
|||||||
|
|
||||||
let mut counter: u32 = 0;
|
let mut counter: u32 = 0;
|
||||||
loop {
|
loop {
|
||||||
let (f, l) = locate_diffs(input.bytes(), other.bytes());
|
let (f, l) = locate_diffs(input.bytes(), other.bytes())?;
|
||||||
|
|
||||||
if f != l && f >= 0 && l >= 2 {
|
if f != l && f >= 0 && l >= 2 {
|
||||||
break (f as u64, l as u64);
|
break (f as u64, l as u64);
|
||||||
|
@ -1867,13 +1867,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_read_tokens() {
|
fn test_read_tokens() {
|
||||||
let _res = fs::remove_file("test.tkns");
|
let _res = fs::remove_file("test.tkns");
|
||||||
let data = r###"
|
let data = r#"
|
||||||
# comment
|
# comment
|
||||||
token1@123="AAA"
|
token1@123="AAA"
|
||||||
token1="A\x41A"
|
token1="A\x41A"
|
||||||
"A\AA"
|
"A\AA"
|
||||||
token2="B"
|
token2="B"
|
||||||
"###;
|
"#;
|
||||||
fs::write("test.tkns", data).expect("Unable to write test.tkns");
|
fs::write("test.tkns", data).expect("Unable to write test.tkns");
|
||||||
let tokens = Tokens::from_file("test.tkns").unwrap();
|
let tokens = Tokens::from_file("test.tkns").unwrap();
|
||||||
log::info!("Token file entries: {:?}", tokens.tokens());
|
log::info!("Token file entries: {:?}", tokens.tokens());
|
||||||
|
@ -148,10 +148,8 @@ where
|
|||||||
for id in state.corpus().ids() {
|
for id in state.corpus().ids() {
|
||||||
let was_fuzzed = state.testcase(id)?.scheduled_count() > 0;
|
let was_fuzzed = state.testcase(id)?.scheduled_count() > 0;
|
||||||
if !was_fuzzed {
|
if !was_fuzzed {
|
||||||
let selection = Some(id);
|
|
||||||
state.metadata_mut::<EcoMetadata>()?.state = EcoState::Exploration;
|
state.metadata_mut::<EcoMetadata>()?.state = EcoState::Exploration;
|
||||||
#[allow(clippy::unnecessary_literal_unwrap)] // false positive
|
return Ok(id);
|
||||||
return Ok(selection.expect("Error in the algorithm, this cannot be None"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ where
|
|||||||
|
|
||||||
let mut start = current_time();
|
let mut start = current_time();
|
||||||
|
|
||||||
let exit_kind = executor.run_target(fuzzer, state, mgr, &input)?;
|
let exit_kind = executor.run_target(fuzzer, state, mgr, &mut input.clone())?;
|
||||||
let mut total_time = if exit_kind == ExitKind::Ok {
|
let mut total_time = if exit_kind == ExitKind::Ok {
|
||||||
current_time() - start
|
current_time() - start
|
||||||
} else {
|
} else {
|
||||||
@ -158,7 +158,7 @@ where
|
|||||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||||
start = current_time();
|
start = current_time();
|
||||||
|
|
||||||
let exit_kind = executor.run_target(fuzzer, state, mgr, &input)?;
|
let exit_kind = executor.run_target(fuzzer, state, mgr, &mut input.clone())?;
|
||||||
if exit_kind != ExitKind::Ok {
|
if exit_kind != ExitKind::Ok {
|
||||||
if !has_errors {
|
if !has_errors {
|
||||||
mgr.log(
|
mgr.log(
|
||||||
|
@ -302,7 +302,7 @@ where
|
|||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
executor.observers_mut().pre_exec_all(state, &input)?;
|
executor.observers_mut().pre_exec_all(state, &input)?;
|
||||||
|
|
||||||
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
let exit_kind = executor.run_target(fuzzer, state, manager, &mut input.clone())?;
|
||||||
|
|
||||||
let observer = executor
|
let observer = executor
|
||||||
.observers()
|
.observers()
|
||||||
|
@ -354,7 +354,7 @@ where
|
|||||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||||
|
|
||||||
start_timer!(state);
|
start_timer!(state);
|
||||||
let exit_kind = executor.run_target(fuzzer, state, manager, input)?;
|
let exit_kind = executor.run_target(fuzzer, state, manager, &mut input.clone())?;
|
||||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||||
|
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
|
@ -276,14 +276,14 @@ where
|
|||||||
push_stage.init(fuzzer, state, event_mgr, executor.observers_mut())?;
|
push_stage.init(fuzzer, state, event_mgr, executor.observers_mut())?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let input =
|
let mut input =
|
||||||
match push_stage.pre_exec(fuzzer, state, event_mgr, executor.observers_mut()) {
|
match push_stage.pre_exec(fuzzer, state, event_mgr, executor.observers_mut()) {
|
||||||
Some(Ok(next_input)) => next_input,
|
Some(Ok(next_input)) => next_input,
|
||||||
Some(Err(err)) => return Err(err),
|
Some(Err(err)) => return Err(err),
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
||||||
let exit_kind = fuzzer.execute_input(state, executor, event_mgr, &input)?;
|
let exit_kind = fuzzer.execute_input(state, executor, event_mgr, &mut input)?;
|
||||||
|
|
||||||
push_stage.post_exec(
|
push_stage.post_exec(
|
||||||
fuzzer,
|
fuzzer,
|
||||||
|
@ -78,7 +78,7 @@ where
|
|||||||
let base_hash = hasher.finish();
|
let base_hash = hasher.finish();
|
||||||
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
mark_feature_time!(state, PerfFeature::GetInputFromCorpus);
|
||||||
|
|
||||||
fuzzer.execute_input(state, executor, manager, &base)?;
|
fuzzer.execute_input(state, executor, manager, &mut base)?;
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
|
|
||||||
let mut feedback = self.create_feedback(observers);
|
let mut feedback = self.create_feedback(observers);
|
||||||
@ -106,7 +106,7 @@ where
|
|||||||
|
|
||||||
let corpus_idx = if input.len() < before_len {
|
let corpus_idx = if input.len() < before_len {
|
||||||
// run the input
|
// run the input
|
||||||
let exit_kind = fuzzer.execute_input(state, executor, manager, &input)?;
|
let exit_kind = fuzzer.execute_input(state, executor, manager, &mut input)?;
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
|
|
||||||
// let the fuzzer process this execution -- it's possible that we find something
|
// let the fuzzer process this execution -- it's possible that we find something
|
||||||
@ -156,7 +156,7 @@ where
|
|||||||
base.hash(&mut hasher);
|
base.hash(&mut hasher);
|
||||||
let new_hash = hasher.finish();
|
let new_hash = hasher.finish();
|
||||||
if base_hash != new_hash {
|
if base_hash != new_hash {
|
||||||
let exit_kind = fuzzer.execute_input(state, executor, manager, &base)?;
|
let exit_kind = fuzzer.execute_input(state, executor, manager, &mut base)?;
|
||||||
let observers = executor.observers();
|
let observers = executor.observers();
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
// assumption: this input should not be marked interesting because it was not
|
// assumption: this input should not be marked interesting because it was not
|
||||||
|
@ -62,9 +62,9 @@ where
|
|||||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||||
|
|
||||||
start_timer!(state);
|
start_timer!(state);
|
||||||
let exit_kind = self
|
let exit_kind =
|
||||||
.tracer_executor
|
self.tracer_executor
|
||||||
.run_target(fuzzer, state, manager, &input)?;
|
.run_target(fuzzer, state, manager, &mut input.clone())?;
|
||||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||||
|
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
@ -138,7 +138,8 @@ where
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// First run with the un-mutated input
|
// First run with the un-mutated input
|
||||||
|
|
||||||
let unmutated_input = state.corpus().cloned_input_for_id(corpus_idx)?;
|
let original_unmutated_input = state.corpus().cloned_input_for_id(corpus_idx)?;
|
||||||
|
let mut unmutated_input = state.corpus().cloned_input_for_id(corpus_idx)?;
|
||||||
|
|
||||||
if let Some(name) = &self.cmplog_observer_name {
|
if let Some(name) = &self.cmplog_observer_name {
|
||||||
if let Some(ob) = self
|
if let Some(ob) = self
|
||||||
@ -156,17 +157,19 @@ where
|
|||||||
|
|
||||||
self.tracer_executor
|
self.tracer_executor
|
||||||
.observers_mut()
|
.observers_mut()
|
||||||
.pre_exec_all(state, &unmutated_input)?;
|
.pre_exec_all(state, &original_unmutated_input)?;
|
||||||
|
|
||||||
let exit_kind =
|
let exit_kind =
|
||||||
self.tracer_executor
|
self.tracer_executor
|
||||||
.run_target(fuzzer, state, manager, &unmutated_input)?;
|
.run_target(fuzzer, state, manager, &mut unmutated_input)?;
|
||||||
|
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
|
|
||||||
self.tracer_executor
|
self.tracer_executor.observers_mut().post_exec_all(
|
||||||
.observers_mut()
|
state,
|
||||||
.post_exec_all(state, &unmutated_input, &exit_kind)?;
|
&original_unmutated_input,
|
||||||
|
&exit_kind,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Second run with the mutated input
|
// Second run with the mutated input
|
||||||
let mutated_input = match state.metadata_map().get::<TaintMetadata>() {
|
let mutated_input = match state.metadata_map().get::<TaintMetadata>() {
|
||||||
@ -192,9 +195,9 @@ where
|
|||||||
.observers_mut()
|
.observers_mut()
|
||||||
.pre_exec_all(state, &mutated_input)?;
|
.pre_exec_all(state, &mutated_input)?;
|
||||||
|
|
||||||
let exit_kind = self
|
let exit_kind =
|
||||||
.tracer_executor
|
self.tracer_executor
|
||||||
.run_target(fuzzer, state, manager, &mutated_input)?;
|
.run_target(fuzzer, state, manager, &mut mutated_input.clone())?;
|
||||||
|
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
|
|
||||||
@ -280,7 +283,7 @@ where
|
|||||||
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
mark_feature_time!(state, PerfFeature::PreExecObservers);
|
||||||
|
|
||||||
start_timer!(state);
|
start_timer!(state);
|
||||||
let exit_kind = executor.run_target(fuzzer, state, manager, &input)?;
|
let exit_kind = executor.run_target(fuzzer, state, manager, &mut input.clone())?;
|
||||||
mark_feature_time!(state, PerfFeature::TargetExecution);
|
mark_feature_time!(state, PerfFeature::TargetExecution);
|
||||||
|
|
||||||
*state.executions_mut() += 1;
|
*state.executions_mut() += 1;
|
||||||
|
@ -385,14 +385,13 @@ impl Allocator {
|
|||||||
metadatas.sort_by(|a, b| a.address.cmp(&b.address));
|
metadatas.sort_by(|a, b| a.address.cmp(&b.address));
|
||||||
let mut offset_to_closest = i64::max_value();
|
let mut offset_to_closest = i64::max_value();
|
||||||
let mut closest = None;
|
let mut closest = None;
|
||||||
|
let ptr: i64 = ptr.try_into().unwrap();
|
||||||
for metadata in metadatas {
|
for metadata in metadatas {
|
||||||
|
let address: i64 = metadata.address.try_into().unwrap();
|
||||||
let new_offset = if hint_base == metadata.address {
|
let new_offset = if hint_base == metadata.address {
|
||||||
(ptr as i64 - metadata.address as i64).abs()
|
(ptr - address).abs()
|
||||||
} else {
|
} else {
|
||||||
std::cmp::min(
|
std::cmp::min(offset_to_closest, (ptr - address).abs())
|
||||||
offset_to_closest,
|
|
||||||
(ptr as i64 - metadata.address as i64).abs(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
if new_offset < offset_to_closest {
|
if new_offset < offset_to_closest {
|
||||||
offset_to_closest = new_offset;
|
offset_to_closest = new_offset;
|
||||||
|
@ -251,14 +251,13 @@ impl AsanErrors {
|
|||||||
cs.set_skipdata(true).expect("failed to set skipdata");
|
cs.set_skipdata(true).expect("failed to set skipdata");
|
||||||
|
|
||||||
let start_pc = error.pc - 4 * 5;
|
let start_pc = error.pc - 4 * 5;
|
||||||
for insn in cs
|
for insn in &*cs
|
||||||
.disasm_count(
|
.disasm_count(
|
||||||
unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 4 * 11) },
|
unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 4 * 11) },
|
||||||
start_pc as u64,
|
start_pc as u64,
|
||||||
11,
|
11,
|
||||||
)
|
)
|
||||||
.expect("failed to disassemble instructions")
|
.expect("failed to disassemble instructions")
|
||||||
.iter()
|
|
||||||
{
|
{
|
||||||
if insn.address() as usize == error.pc {
|
if insn.address() as usize == error.pc {
|
||||||
output
|
output
|
||||||
@ -276,7 +275,9 @@ impl AsanErrors {
|
|||||||
|
|
||||||
#[allow(clippy::non_ascii_literal)]
|
#[allow(clippy::non_ascii_literal)]
|
||||||
writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap();
|
writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap();
|
||||||
let offset: i64 = fault_address as i64 - (error.metadata.address + 0x1000) as i64;
|
let fault_address: i64 = fault_address.try_into().unwrap();
|
||||||
|
let metadata_address: i64 = error.metadata.address.try_into().unwrap();
|
||||||
|
let offset: i64 = fault_address - (metadata_address + 0x1000);
|
||||||
let direction = if offset > 0 { "right" } else { "left" };
|
let direction = if offset > 0 { "right" } else { "left" };
|
||||||
writeln!(
|
writeln!(
|
||||||
output,
|
output,
|
||||||
@ -505,14 +506,13 @@ impl AsanErrors {
|
|||||||
cs.set_skipdata(true).expect("failed to set skipdata");
|
cs.set_skipdata(true).expect("failed to set skipdata");
|
||||||
|
|
||||||
let start_pc = pc;
|
let start_pc = pc;
|
||||||
for insn in cs
|
for insn in &*cs
|
||||||
.disasm_count(
|
.disasm_count(
|
||||||
unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 4 * 11) },
|
unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 4 * 11) },
|
||||||
start_pc as u64,
|
start_pc as u64,
|
||||||
11,
|
11,
|
||||||
)
|
)
|
||||||
.expect("failed to disassemble instructions")
|
.expect("failed to disassemble instructions")
|
||||||
.iter()
|
|
||||||
{
|
{
|
||||||
if insn.address() as usize == pc {
|
if insn.address() as usize == pc {
|
||||||
output
|
output
|
||||||
|
@ -150,7 +150,7 @@ impl CoverageRuntime {
|
|||||||
; mov QWORD [rsp-0x98], rbx
|
; mov QWORD [rsp-0x98], rbx
|
||||||
|
|
||||||
// Load the previous_pc
|
// Load the previous_pc
|
||||||
; mov rax, QWORD prev_loc_ptr as *mut u64 as _
|
; mov rax, QWORD prev_loc_ptr as _
|
||||||
; mov rax, QWORD [rax]
|
; mov rax, QWORD [rax]
|
||||||
|
|
||||||
// Calculate the edge id
|
// Calculate the edge id
|
||||||
@ -158,7 +158,7 @@ impl CoverageRuntime {
|
|||||||
; xor rax, rbx
|
; xor rax, rbx
|
||||||
|
|
||||||
// Load the map byte address
|
// Load the map byte address
|
||||||
; mov rbx, QWORD map_addr_ptr as *mut [u8; MAP_SIZE] as _
|
; mov rbx, QWORD map_addr_ptr as _
|
||||||
; add rax, rbx
|
; add rax, rbx
|
||||||
|
|
||||||
// Update the map byte
|
// Update the map byte
|
||||||
@ -168,7 +168,7 @@ impl CoverageRuntime {
|
|||||||
; mov BYTE [rax],bl
|
; mov BYTE [rax],bl
|
||||||
|
|
||||||
// Update the previous_pc value
|
// Update the previous_pc value
|
||||||
; mov rax, QWORD prev_loc_ptr as *mut u64 as _
|
; mov rax, QWORD prev_loc_ptr as _
|
||||||
; mov ebx, WORD (h64 >> 1) as i32
|
; mov ebx, WORD (h64 >> 1) as i32
|
||||||
; mov QWORD [rax], rbx
|
; mov QWORD [rax], rbx
|
||||||
|
|
||||||
|
@ -24,10 +24,12 @@ use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple};
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::windows_hooks::initialize;
|
use crate::windows_hooks::initialize;
|
||||||
|
|
||||||
/// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation.
|
/// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the
|
||||||
|
/// same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation. It is
|
||||||
|
/// the same as [`FridaInProcessExecutor`] except it allows mutating the input
|
||||||
pub struct FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
pub struct FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -44,7 +46,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'b, 'c, H, OT, RT, S> Debug for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
impl<'a, 'b, 'c, H, OT, RT, S> Debug for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -62,7 +64,7 @@ impl<'a, 'b, 'c, EM, H, OT, RT, S, Z> Executor<EM, Z>
|
|||||||
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -76,7 +78,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
self.helper.pre_exec(input)?;
|
self.helper.pre_exec(input)?;
|
||||||
if self.helper.stalker_enabled() {
|
if self.helper.stalker_enabled() {
|
||||||
@ -106,7 +108,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'b, 'c, H, OT, RT, S> UsesObservers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
impl<'a, 'b, 'c, H, OT, RT, S> UsesObservers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
@ -116,7 +118,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'b, 'c, H, OT, RT, S> UsesState for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
impl<'a, 'b, 'c, H, OT, RT, S> UsesState for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
@ -126,7 +128,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'b, 'c, H, OT, RT, S> HasObservers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
impl<'a, 'b, 'c, H, OT, RT, S> HasObservers for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -144,7 +146,7 @@ where
|
|||||||
|
|
||||||
impl<'a, 'b, 'c, H, OT, S, RT> FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
impl<'a, 'b, 'c, H, OT, S, RT> FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
@ -199,7 +201,7 @@ where
|
|||||||
impl<'a, 'b, 'c, H, OT, RT, S> HasInProcessHandlers
|
impl<'a, 'b, 'c, H, OT, RT, S> HasInProcessHandlers
|
||||||
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
for FridaInProcessExecutor<'a, 'b, 'c, H, OT, RT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput + HasClientPerfMonitor + HasSolutions + HasCorpus + HasExecutions,
|
S: UsesInput + HasClientPerfMonitor + HasSolutions + HasCorpus + HasExecutions,
|
||||||
S::Input: HasTargetBytes,
|
S::Input: HasTargetBytes,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
|
@ -57,7 +57,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let input_owned = input.target_bytes();
|
let input_owned = input.target_bytes();
|
||||||
let input = input_owned.as_slice();
|
let input = input_owned.as_slice();
|
||||||
|
@ -395,7 +395,7 @@ impl AsanGiovese {
|
|||||||
if self.snapshot_shadow {
|
if self.snapshot_shadow {
|
||||||
let set = self.dirty_shadow.lock().unwrap();
|
let set = self.dirty_shadow.lock().unwrap();
|
||||||
|
|
||||||
for &page in set.iter() {
|
for &page in &*set {
|
||||||
let data = Self::get_shadow_page(emu, page).to_vec();
|
let data = Self::get_shadow_page(emu, page).to_vec();
|
||||||
self.saved_shadow.insert(page, data);
|
self.saved_shadow.insert(page, data);
|
||||||
}
|
}
|
||||||
@ -425,7 +425,7 @@ impl AsanGiovese {
|
|||||||
if self.snapshot_shadow {
|
if self.snapshot_shadow {
|
||||||
let mut set = self.dirty_shadow.lock().unwrap();
|
let mut set = self.dirty_shadow.lock().unwrap();
|
||||||
|
|
||||||
for &page in set.iter() {
|
for &page in &*set {
|
||||||
let original = self.saved_shadow.get(&page);
|
let original = self.saved_shadow.get(&page);
|
||||||
if let Some(data) = original {
|
if let Some(data) = original {
|
||||||
let cur = Self::get_shadow_page(emu, page);
|
let cur = Self::get_shadow_page(emu, page);
|
||||||
@ -472,7 +472,7 @@ pub fn init_with_asan(
|
|||||||
|e: &str| "LD_PRELOAD=".to_string() + &asan_lib + " " + &e["LD_PRELOAD=".len()..];
|
|e: &str| "LD_PRELOAD=".to_string() + &asan_lib + " " + &e["LD_PRELOAD=".len()..];
|
||||||
|
|
||||||
let mut added = false;
|
let mut added = false;
|
||||||
for (k, v) in env.iter_mut() {
|
for (k, v) in &mut *env {
|
||||||
if k == "QEMU_SET_ENV" {
|
if k == "QEMU_SET_ENV" {
|
||||||
let mut new_v = vec![];
|
let mut new_v = vec![];
|
||||||
for e in v.split(',') {
|
for e in v.split(',') {
|
||||||
|
@ -102,8 +102,8 @@ where
|
|||||||
if self.full_trace {
|
if self.full_trace {
|
||||||
if DRCOV_IDS.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
if DRCOV_IDS.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
||||||
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
||||||
for id in DRCOV_IDS.lock().unwrap().as_ref().unwrap().iter() {
|
for id in DRCOV_IDS.lock().unwrap().as_ref().unwrap() {
|
||||||
'pcs_full: for (pc, idm) in DRCOV_MAP.lock().unwrap().as_ref().unwrap().iter() {
|
'pcs_full: for (pc, idm) in DRCOV_MAP.lock().unwrap().as_ref().unwrap() {
|
||||||
let mut module_found = false;
|
let mut module_found = false;
|
||||||
for module in self.module_mapping.iter() {
|
for module in self.module_mapping.iter() {
|
||||||
let (range, (_, _)) = module;
|
let (range, (_, _)) = module;
|
||||||
@ -141,7 +141,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
if DRCOV_MAP.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
if DRCOV_MAP.lock().unwrap().as_ref().unwrap().len() > self.drcov_len {
|
||||||
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
let mut drcov_vec = Vec::<DrCovBasicBlock>::new();
|
||||||
'pcs: for (pc, _) in DRCOV_MAP.lock().unwrap().as_ref().unwrap().iter() {
|
'pcs: for (pc, _) in DRCOV_MAP.lock().unwrap().as_ref().unwrap() {
|
||||||
let mut module_found = false;
|
let mut module_found = false;
|
||||||
for module in self.module_mapping.iter() {
|
for module in self.module_mapping.iter() {
|
||||||
let (range, (_, _)) = module;
|
let (range, (_, _)) = module;
|
||||||
|
@ -41,7 +41,7 @@ impl<'a> EasyElf<'a> {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn resolve_symbol(&self, name: &str, load_addr: GuestAddr) -> Option<GuestAddr> {
|
pub fn resolve_symbol(&self, name: &str, load_addr: GuestAddr) -> Option<GuestAddr> {
|
||||||
for sym in self.elf.syms.iter() {
|
for sym in &self.elf.syms {
|
||||||
if let Some(sym_name) = self.elf.strtab.get_at(sym.st_name) {
|
if let Some(sym_name) = self.elf.strtab.get_at(sym.st_name) {
|
||||||
if sym_name == name {
|
if sym_name == name {
|
||||||
return if sym.st_value == 0 {
|
return if sym.st_value == 0 {
|
||||||
|
@ -739,18 +739,10 @@ impl Emulator {
|
|||||||
envp.push(null());
|
envp.push(null());
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
qemu_user_init(
|
qemu_user_init(argc, argv.as_ptr(), envp.as_ptr());
|
||||||
argc,
|
|
||||||
argv.as_ptr() as *const *const u8,
|
|
||||||
envp.as_ptr() as *const *const u8,
|
|
||||||
);
|
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
{
|
{
|
||||||
qemu_init(
|
qemu_init(argc, argv.as_ptr(), envp.as_ptr());
|
||||||
argc,
|
|
||||||
argv.as_ptr() as *const *const u8,
|
|
||||||
envp.as_ptr() as *const *const u8,
|
|
||||||
);
|
|
||||||
libc::atexit(qemu_cleanup_atexit);
|
libc::atexit(qemu_cleanup_atexit);
|
||||||
libafl_qemu_sys::syx_snapshot_init();
|
libafl_qemu_sys::syx_snapshot_init();
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use crate::{emu::Emulator, helper::QemuHelperTuple, hooks::QemuHooks};
|
|||||||
|
|
||||||
pub struct QemuExecutor<'a, H, OT, QT, S>
|
pub struct QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -33,7 +33,7 @@ where
|
|||||||
|
|
||||||
impl<'a, H, OT, QT, S> Debug for QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, H, OT, QT, S> Debug for QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -48,7 +48,7 @@ where
|
|||||||
|
|
||||||
impl<'a, H, OT, QT, S> QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, H, OT, QT, S> QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -101,7 +101,7 @@ where
|
|||||||
impl<'a, EM, H, OT, QT, S, Z> Executor<EM, Z> for QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, EM, H, OT, QT, S, Z> Executor<EM, Z> for QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
EM: UsesState<State = S>,
|
EM: UsesState<State = S>,
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -112,7 +112,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let emu = Emulator::new_empty();
|
let emu = Emulator::new_empty();
|
||||||
if self.first_exec {
|
if self.first_exec {
|
||||||
@ -133,7 +133,7 @@ where
|
|||||||
|
|
||||||
impl<'a, H, OT, QT, S> UsesState for QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, H, OT, QT, S> UsesState for QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -143,7 +143,7 @@ where
|
|||||||
|
|
||||||
impl<'a, H, OT, QT, S> UsesObservers for QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, H, OT, QT, S> UsesObservers for QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -153,7 +153,7 @@ where
|
|||||||
|
|
||||||
impl<'a, H, OT, QT, S> HasObservers for QemuExecutor<'a, H, OT, QT, S>
|
impl<'a, H, OT, QT, S> HasObservers for QemuExecutor<'a, H, OT, QT, S>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -172,7 +172,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
pub struct QemuForkExecutor<'a, H, OT, QT, S, SP>
|
pub struct QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -186,7 +186,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<'a, H, OT, QT, S, SP> Debug for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, H, OT, QT, S, SP> Debug for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -203,7 +203,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<'a, H, OT, QT, S, SP> QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, H, OT, QT, S, SP> QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput + HasCorpus,
|
S: UsesInput + HasCorpus,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -268,7 +268,7 @@ where
|
|||||||
impl<'a, EM, H, OT, QT, S, Z, SP> Executor<EM, Z> for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, EM, H, OT, QT, S, Z, SP> Executor<EM, Z> for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
EM: EventManager<InProcessForkExecutor<'a, H, OT, S, SP>, Z, State = S>,
|
EM: EventManager<InProcessForkExecutor<'a, H, OT, S, SP>, Z, State = S>,
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput + HasClientPerfMonitor + HasMetadata + HasExecutions,
|
S: UsesInput + HasClientPerfMonitor + HasMetadata + HasExecutions,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
@ -280,7 +280,7 @@ where
|
|||||||
fuzzer: &mut Z,
|
fuzzer: &mut Z,
|
||||||
state: &mut Self::State,
|
state: &mut Self::State,
|
||||||
mgr: &mut EM,
|
mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
let emu = Emulator::new_empty();
|
let emu = Emulator::new_empty();
|
||||||
if self.first_exec {
|
if self.first_exec {
|
||||||
@ -302,7 +302,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<'a, H, OT, QT, S, SP> UsesObservers for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, H, OT, QT, S, SP> UsesObservers for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -314,7 +314,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<'a, H, OT, QT, S, SP> UsesState for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, H, OT, QT, S, SP> UsesState for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
@ -326,7 +326,7 @@ where
|
|||||||
#[cfg(feature = "fork")]
|
#[cfg(feature = "fork")]
|
||||||
impl<'a, H, OT, QT, S, SP> HasObservers for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
impl<'a, H, OT, QT, S, SP> HasObservers for QemuForkExecutor<'a, H, OT, QT, S, SP>
|
||||||
where
|
where
|
||||||
H: FnMut(&S::Input) -> ExitKind,
|
H: FnMut(&mut S::Input) -> ExitKind,
|
||||||
S: UsesInput,
|
S: UsesInput,
|
||||||
OT: ObserversTuple<S>,
|
OT: ObserversTuple<S>,
|
||||||
QT: QemuHelperTuple<S>,
|
QT: QemuHelperTuple<S>,
|
||||||
|
@ -211,7 +211,7 @@ impl QemuSnapshotHelper {
|
|||||||
{
|
{
|
||||||
let new_maps = self.new_maps.get_mut().unwrap();
|
let new_maps = self.new_maps.get_mut().unwrap();
|
||||||
|
|
||||||
for acc in self.accesses.iter_mut() {
|
for acc in &mut self.accesses {
|
||||||
unsafe { &mut (*acc.get()) }.dirty.retain(|page| {
|
unsafe { &mut (*acc.get()) }.dirty.retain(|page| {
|
||||||
if let Some(info) = self.pages.get_mut(page) {
|
if let Some(info) = self.pages.get_mut(page) {
|
||||||
// TODO avoid duplicated memcpy
|
// TODO avoid duplicated memcpy
|
||||||
@ -251,7 +251,7 @@ impl QemuSnapshotHelper {
|
|||||||
self.reset_maps(emulator);
|
self.reset_maps(emulator);
|
||||||
|
|
||||||
// This one is after that we remapped potential regions mapped at snapshot time but unmapped during execution
|
// This one is after that we remapped potential regions mapped at snapshot time but unmapped during execution
|
||||||
for acc in self.accesses.iter_mut() {
|
for acc in &mut self.accesses {
|
||||||
for page in unsafe { &(*acc.get()).dirty } {
|
for page in unsafe { &(*acc.get()).dirty } {
|
||||||
for entry in self
|
for entry in self
|
||||||
.maps
|
.maps
|
||||||
|
@ -193,7 +193,7 @@ where
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
(harness_bytes)(buf);
|
(harness_bytes)(buf);
|
||||||
|
@ -204,7 +204,7 @@ where
|
|||||||
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
// The wrapped harness function, calling out to the LLVM-style harness
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &mut BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
let buf = target.as_slice();
|
let buf = target.as_slice();
|
||||||
(harness_bytes)(buf);
|
(harness_bytes)(buf);
|
||||||
|
@ -165,7 +165,7 @@ mod observers {
|
|||||||
let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher();
|
let mut hasher = RandomState::with_seeds(0, 0, 0, 0).build_hasher();
|
||||||
for map in unsafe { &COUNTERS_MAPS } {
|
for map in unsafe { &COUNTERS_MAPS } {
|
||||||
let slice = map.as_slice();
|
let slice = map.as_slice();
|
||||||
let ptr = slice.as_ptr() as *const u8;
|
let ptr = slice.as_ptr();
|
||||||
let map_size = slice.len() / core::mem::size_of::<u8>();
|
let map_size = slice.len() / core::mem::size_of::<u8>();
|
||||||
unsafe {
|
unsafe {
|
||||||
hasher.write(from_raw_parts(ptr, map_size));
|
hasher.write(from_raw_parts(ptr, map_size));
|
||||||
|
@ -22,11 +22,11 @@ pub unsafe extern "C" fn __sanitizer_cov_trace_pc_guard(guard: *mut u32) {
|
|||||||
{
|
{
|
||||||
#[cfg(feature = "sancov_pcguard_edges")]
|
#[cfg(feature = "sancov_pcguard_edges")]
|
||||||
{
|
{
|
||||||
(EDGES_MAP_PTR as *mut u8).add(pos).write(1);
|
(EDGES_MAP_PTR).add(pos).write(1);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sancov_pcguard_hitcounts")]
|
#[cfg(feature = "sancov_pcguard_hitcounts")]
|
||||||
{
|
{
|
||||||
let addr = (EDGES_MAP_PTR as *mut u8).add(pos);
|
let addr = (EDGES_MAP_PTR).add(pos);
|
||||||
let val = addr.read().wrapping_add(1);
|
let val = addr.read().wrapping_add(1);
|
||||||
addr.write(val);
|
addr.write(val);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ where
|
|||||||
_fuzzer: &mut Z,
|
_fuzzer: &mut Z,
|
||||||
_state: &mut Self::State,
|
_state: &mut Self::State,
|
||||||
_mgr: &mut EM,
|
_mgr: &mut EM,
|
||||||
input: &Self::Input,
|
input: &mut Self::Input,
|
||||||
) -> Result<ExitKind, Error> {
|
) -> Result<ExitKind, Error> {
|
||||||
match &self.map {
|
match &self.map {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
@ -208,7 +208,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton {
|
|||||||
//let mut culled_pda_unique = HashSet::new();
|
//let mut culled_pda_unique = HashSet::new();
|
||||||
|
|
||||||
for final_state in &finals {
|
for final_state in &finals {
|
||||||
for transition in pda.iter() {
|
for transition in pda {
|
||||||
if transition.dest == *final_state && transition.stack.len() > 0 {
|
if transition.dest == *final_state && transition.stack.len() > 0 {
|
||||||
blocklist.insert(transition.dest);
|
blocklist.insert(transition.dest);
|
||||||
} else {
|
} else {
|
||||||
@ -267,7 +267,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Running FSA construction in exact approximation mode and postprocessing it like so
|
// Running FSA construction in exact approximation mode and postprocessing it like so
|
||||||
for transition in pda.iter() {
|
for transition in pda {
|
||||||
num_transition += 1;
|
num_transition += 1;
|
||||||
let state = transition.source;
|
let state = transition.source;
|
||||||
if state >= memoized.len() {
|
if state >= memoized.len() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user