Partially Revert #3029 and #3053 (#3063)

* revert begins

* fixer

* e?

* fixer

* how you didn't report that at the same time though???

* i'm tired of you
This commit is contained in:
Dongjia "toka" Zhang 2025-03-11 12:53:27 +01:00 committed by GitHub
parent 115672904e
commit f4cb9a827d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 208 additions and 305 deletions

View File

@ -24,7 +24,7 @@ use windows::Win32::System::Threading::{CRITICAL_SECTION, PTP_TIMER};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::executors::hooks::timer::TimerStruct; use crate::executors::hooks::timer::TimerStruct;
use crate::{ use crate::{
Error, HasFeedback, HasObjective, HasScheduler, Error, HasObjective,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{Executor, HasObservers, hooks::ExecutorHook, inprocess::HasInProcessHooks}, executors::{Executor, HasObservers, hooks::ExecutorHook, inprocess::HasInProcessHooks},
feedbacks::Feedback, feedbacks::Feedback,
@ -232,15 +232,14 @@ impl<I, S> InProcessHooks<I, S> {
/// Create new [`InProcessHooks`]. /// Create new [`InProcessHooks`].
#[cfg(unix)] #[cfg(unix)]
#[allow(unused_variables)] // for `exec_tmout` without `std` #[allow(unused_variables)] // for `exec_tmout` without `std`
pub fn new<E, EM, F, OF, Z>(exec_tmout: Duration) -> Result<Self, Error> pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
where where
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>, E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
// # Safety // # Safety
@ -250,7 +249,7 @@ impl<I, S> InProcessHooks<I, S> {
#[cfg(all(not(miri), unix, feature = "std"))] #[cfg(all(not(miri), unix, feature = "std"))]
let data = unsafe { &raw mut GLOBAL_STATE }; let data = unsafe { &raw mut GLOBAL_STATE };
#[cfg(feature = "std")] #[cfg(feature = "std")]
unix_signal_handler::setup_panic_hook::<E, EM, F, I, OF, S, Z>(); unix_signal_handler::setup_panic_hook::<E, EM, I, OF, S, Z>();
// # Safety // # Safety
// Setting up the signal handlers with a pointer to the `GLOBAL_STATE` which should not be NULL at this point. // Setting up the signal handlers with a pointer to the `GLOBAL_STATE` which should not be NULL at this point.
// We are the sole users of `GLOBAL_STATE` right now, and only dereference it in case of Segfault/Panic. // We are the sole users of `GLOBAL_STATE` right now, and only dereference it in case of Segfault/Panic.
@ -263,10 +262,10 @@ impl<I, S> InProcessHooks<I, S> {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
Ok(Self { Ok(Self {
#[cfg(feature = "std")] #[cfg(feature = "std")]
crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, F, I, OF, S, Z> crash_handler: unix_signal_handler::inproc_crash_handler::<E, EM, I, OF, S, Z>
as *const c_void, as *const c_void,
#[cfg(feature = "std")] #[cfg(feature = "std")]
timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, F, I, OF, S, Z> timeout_handler: unix_signal_handler::inproc_timeout_handler::<E, EM, I, OF, S, Z>
as *const _, as *const _,
#[cfg(feature = "std")] #[cfg(feature = "std")]
timer: TimerStruct::new(exec_tmout), timer: TimerStruct::new(exec_tmout),
@ -277,16 +276,15 @@ impl<I, S> InProcessHooks<I, S> {
/// Create new [`InProcessHooks`]. /// Create new [`InProcessHooks`].
#[cfg(windows)] #[cfg(windows)]
#[allow(unused_variables)] // for `exec_tmout` without `std` #[allow(unused_variables)] // for `exec_tmout` without `std`
pub fn new<E, EM, F, OF, Z>(exec_tmout: Duration) -> Result<Self, Error> pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
where where
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>, E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let ret; let ret;
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -295,7 +293,6 @@ impl<I, S> InProcessHooks<I, S> {
crate::executors::hooks::windows::windows_exception_handler::setup_panic_hook::< crate::executors::hooks::windows::windows_exception_handler::setup_panic_hook::<
E, E,
EM, EM,
F,
I, I,
OF, OF,
S, S,
@ -307,7 +304,6 @@ impl<I, S> InProcessHooks<I, S> {
crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::< crate::executors::hooks::windows::windows_exception_handler::inproc_crash_handler::<
E, E,
EM, EM,
F,
I, I,
OF, OF,
S, S,
@ -317,7 +313,6 @@ impl<I, S> InProcessHooks<I, S> {
crate::executors::hooks::windows::windows_exception_handler::inproc_timeout_handler::< crate::executors::hooks::windows::windows_exception_handler::inproc_timeout_handler::<
E, E,
EM, EM,
F,
I, I,
OF, OF,
S, S,
@ -344,14 +339,13 @@ impl<I, S> InProcessHooks<I, S> {
/// Create a new [`InProcessHooks`] /// Create a new [`InProcessHooks`]
#[cfg(all(not(unix), not(windows)))] #[cfg(all(not(unix), not(windows)))]
#[expect(unused_variables)] #[expect(unused_variables)]
pub fn new<E, EM, F, OF, Z>(exec_tmout: Duration) -> Result<Self, Error> pub fn new<E, EM, OF, Z>(exec_tmout: Duration) -> Result<Self, Error>
where where
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>, E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I>, S: HasExecutions + HasSolutions<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
#[cfg_attr(miri, allow(unused_variables))] #[cfg_attr(miri, allow(unused_variables))]
let ret = Self { let ret = Self {
@ -478,7 +472,7 @@ impl InProcessExecutorHandlerData {
/// ///
/// Should only be called to signal a crash in the target /// Should only be called to signal a crash in the target
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
pub unsafe fn maybe_report_crash<E, EM, F, I, OF, S, Z>( pub unsafe fn maybe_report_crash<E, EM, I, OF, S, Z>(
&mut self, &mut self,
bsod_info: Option<BsodInfo>, bsod_info: Option<BsodInfo>,
) -> bool ) -> bool
@ -486,10 +480,9 @@ impl InProcessExecutorHandlerData {
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
unsafe { unsafe {
@ -517,7 +510,7 @@ impl InProcessExecutorHandlerData {
} }
} }
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,

View File

@ -12,7 +12,6 @@ pub mod unix_signal_handler {
use libc::siginfo_t; use libc::siginfo_t;
use crate::{ use crate::{
HasFeedback, HasScheduler,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, common_signals, Executor, ExitKind, HasObservers, common_signals,
@ -87,15 +86,14 @@ pub mod unix_signal_handler {
} }
/// invokes the `post_exec` hook on all observer in case of panic /// invokes the `post_exec` hook on all observer in case of panic
pub fn setup_panic_hook<E, EM, F, I, OF, S, Z>() pub fn setup_panic_hook<E, EM, I, OF, S, Z>()
where where
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
let old_hook = panic::take_hook(); let old_hook = panic::take_hook();
@ -119,7 +117,7 @@ pub mod unix_signal_handler {
let fuzzer = (*data).fuzzer_mut::<Z>(); let fuzzer = (*data).fuzzer_mut::<Z>();
let event_mgr = (*data).event_mgr_mut::<EM>(); let event_mgr = (*data).event_mgr_mut::<EM>();
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,
@ -142,7 +140,7 @@ pub mod unix_signal_handler {
/// Well, signal handling is not safe /// Well, signal handling is not safe
#[cfg(unix)] #[cfg(unix)]
#[allow(clippy::needless_pass_by_value)] // nightly no longer requires this #[allow(clippy::needless_pass_by_value)] // nightly no longer requires this
pub unsafe fn inproc_timeout_handler<E, EM, F, I, OF, S, Z>( pub unsafe fn inproc_timeout_handler<E, EM, I, OF, S, Z>(
_signal: Signal, _signal: Signal,
_info: &mut siginfo_t, _info: &mut siginfo_t,
_context: Option<&mut ucontext_t>, _context: Option<&mut ucontext_t>,
@ -151,10 +149,9 @@ pub mod unix_signal_handler {
E: HasInProcessHooks<I, S> + HasObservers, E: HasInProcessHooks<I, S> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
unsafe { unsafe {
@ -181,7 +178,7 @@ pub mod unix_signal_handler {
log::error!("Timeout in fuzz run."); log::error!("Timeout in fuzz run.");
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,
@ -201,7 +198,7 @@ pub mod unix_signal_handler {
/// # Safety /// # Safety
/// Well, signal handling is not safe /// Well, signal handling is not safe
#[allow(clippy::needless_pass_by_value)] // nightly no longer requires this #[allow(clippy::needless_pass_by_value)] // nightly no longer requires this
pub unsafe fn inproc_crash_handler<E, EM, F, I, OF, S, Z>( pub unsafe fn inproc_crash_handler<E, EM, I, OF, S, Z>(
signal: Signal, signal: Signal,
_info: &mut siginfo_t, _info: &mut siginfo_t,
_context: Option<&mut ucontext_t>, _context: Option<&mut ucontext_t>,
@ -210,10 +207,9 @@ pub mod unix_signal_handler {
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
unsafe { unsafe {
@ -255,7 +251,7 @@ pub mod unix_signal_handler {
} }
} }
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,

View File

@ -9,14 +9,13 @@ pub mod windows_asan_handler {
}; };
use crate::{ use crate::{
HasFeedback,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, hooks::inprocess::GLOBAL_STATE, Executor, ExitKind, HasObservers, hooks::inprocess::GLOBAL_STATE,
inprocess::run_observers_and_save_state, inprocess::run_observers_and_save_state,
}, },
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::{HasObjective, HasScheduler}, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
state::{HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCurrentTestcase, HasExecutions, HasSolutions},
@ -24,16 +23,15 @@ pub mod windows_asan_handler {
/// # Safety /// # Safety
/// ASAN deatch handler /// ASAN deatch handler
pub unsafe extern "C" fn asan_death_handler<E, EM, F, I, OF, S, Z>() pub unsafe extern "C" fn asan_death_handler<E, EM, I, OF, S, Z>()
where where
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
unsafe { unsafe {
let data = &raw mut GLOBAL_STATE; let data = &raw mut GLOBAL_STATE;
@ -96,7 +94,7 @@ pub mod windows_asan_handler {
// Make sure we don't crash in the crash handler forever. // Make sure we don't crash in the crash handler forever.
let input = (*data).take_current_input::<I>(); let input = (*data).take_current_input::<I>();
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,
@ -139,7 +137,6 @@ pub mod windows_exception_handler {
}; };
use crate::{ use crate::{
HasFeedback,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, Executor, ExitKind, HasObservers,
@ -147,7 +144,7 @@ pub mod windows_exception_handler {
inprocess::{HasInProcessHooks, run_observers_and_save_state}, inprocess::{HasInProcessHooks, run_observers_and_save_state},
}, },
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::{HasObjective, HasScheduler}, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
state::{HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCurrentTestcase, HasExecutions, HasSolutions},
@ -200,16 +197,15 @@ pub mod windows_exception_handler {
/// # Safety /// # Safety
/// Well, exception handling is not safe /// Well, exception handling is not safe
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn setup_panic_hook<E, EM, F, I, OF, S, Z>() pub fn setup_panic_hook<E, EM, I, OF, S, Z>()
where where
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let old_hook = panic::take_hook(); let old_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| unsafe { panic::set_hook(Box::new(move |panic_info| unsafe {
@ -246,7 +242,7 @@ pub mod windows_exception_handler {
let input = (*data).take_current_input::<I>(); let input = (*data).take_current_input::<I>();
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,
@ -266,7 +262,7 @@ pub mod windows_exception_handler {
/// ///
/// # Safety /// # Safety
/// Well, exception handling is not safe /// Well, exception handling is not safe
pub unsafe extern "system" fn inproc_timeout_handler<E, EM, F, I, OF, S, Z>( pub unsafe extern "system" fn inproc_timeout_handler<E, EM, I, OF, S, Z>(
_p0: *mut u8, _p0: *mut u8,
global_state: *mut c_void, global_state: *mut c_void,
_p1: *mut u8, _p1: *mut u8,
@ -275,10 +271,9 @@ pub mod windows_exception_handler {
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let data: &mut InProcessExecutorHandlerData = let data: &mut InProcessExecutorHandlerData =
unsafe { &mut *(global_state as *mut InProcessExecutorHandlerData) }; unsafe { &mut *(global_state as *mut InProcessExecutorHandlerData) };
@ -318,7 +313,7 @@ pub mod windows_exception_handler {
let input = unsafe { (data.current_input_ptr as *const I).as_ref().unwrap() }; let input = unsafe { (data.current_input_ptr as *const I).as_ref().unwrap() };
data.current_input_ptr = ptr::null_mut(); data.current_input_ptr = ptr::null_mut();
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,
@ -346,7 +341,7 @@ pub mod windows_exception_handler {
/// ///
/// # Safety /// # Safety
/// Well, exception handling is not safe /// Well, exception handling is not safe
pub unsafe fn inproc_crash_handler<E, EM, F, I, OF, S, Z>( pub unsafe fn inproc_crash_handler<E, EM, I, OF, S, Z>(
exception_pointers: *mut EXCEPTION_POINTERS, exception_pointers: *mut EXCEPTION_POINTERS,
data: &mut InProcessExecutorHandlerData, data: &mut InProcessExecutorHandlerData,
) where ) where
@ -354,10 +349,9 @@ pub mod windows_exception_handler {
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
// Have we set a timer_before? // Have we set a timer_before?
if data.ptp_timer.is_some() { if data.ptp_timer.is_some() {
@ -462,7 +456,7 @@ pub mod windows_exception_handler {
log::warn!("Running observers and exiting!"); log::warn!("Running observers and exiting!");
// // I want to disable the hooks before doing anything, especially before taking a stack dump // // I want to disable the hooks before doing anything, especially before taking a stack dump
let input = unsafe { data.take_current_input::<I>() }; let input = unsafe { data.take_current_input::<I>() };
run_observers_and_save_state::<E, EM, F, I, OF, S, Z>( run_observers_and_save_state::<E, EM, I, OF, S, Z>(
executor, executor,
state, state,
input, input,

View File

@ -14,7 +14,7 @@ use windows::Win32::System::Threading::SetThreadStackGuarantee;
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]
use crate::executors::hooks::inprocess::HasTimeout; use crate::executors::hooks::inprocess::HasTimeout;
use crate::{ use crate::{
Error, HasFeedback, Error,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, HasObservers, Executor, HasObservers,
@ -25,7 +25,7 @@ use crate::{
inprocess::HasInProcessHooks, inprocess::HasInProcessHooks,
}, },
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::{HasObjective, HasScheduler}, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
state::{HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCurrentTestcase, HasExecutions, HasSolutions},
@ -130,7 +130,7 @@ where
S: HasExecutions + HasSolutions<I>, S: HasExecutions + HasSolutions<I>,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<E, F, OF>( pub fn generic<E, OF>(
user_hooks: HT, user_hooks: HT,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -142,12 +142,11 @@ where
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
I: Input + Clone, I: Input + Clone,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasCurrentTestcase<I> + HasSolutions<I>, S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<E, F, OF>( Self::with_timeout_generic::<E, OF>(
user_hooks, user_hooks,
observers, observers,
fuzzer, fuzzer,
@ -165,7 +164,7 @@ where
/// * `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 with_timeout_generic<E, F, OF>( pub fn with_timeout_generic<E, OF>(
user_hooks: HT, user_hooks: HT,
observers: OT, observers: OT,
_fuzzer: &mut Z, _fuzzer: &mut Z,
@ -177,13 +176,12 @@ where
E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>, E: Executor<EM, I, S, Z> + HasObservers + HasInProcessHooks<I, S>,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasCurrentTestcase<I> + HasSolutions<I>, S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
let default = InProcessHooks::new::<E, EM, F, OF, Z>(timeout)?; let default = InProcessHooks::new::<E, EM, OF, Z>(timeout)?;
let mut hooks = tuple_list!(default).merge(user_hooks); let mut hooks = tuple_list!(default).merge(user_hooks);
hooks.init_all(state); hooks.init_all(state);

View File

@ -15,7 +15,7 @@ use core::{
use libafl_bolts::tuples::{RefIndexable, tuple_list}; use libafl_bolts::tuples::{RefIndexable, tuple_list};
use crate::{ use crate::{
Error, HasFeedback, HasScheduler, Error,
corpus::{Corpus, Testcase}, corpus::{Corpus, Testcase},
events::{Event, EventFirer, EventRestarter}, events::{Event, EventFirer, EventRestarter},
executors::{ executors::{
@ -27,7 +27,6 @@ use crate::{
fuzzer::HasObjective, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
schedulers::Scheduler,
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasSolutions},
}; };
@ -133,7 +132,7 @@ where
I: Input, I: Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn new<F, OF>( pub fn new<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -142,11 +141,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<F, OF>( Self::with_timeout_generic::<OF>(
tuple_list!(), tuple_list!(),
harness_fn, harness_fn,
observers, observers,
@ -165,7 +163,7 @@ where
/// * `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 with_timeout<F, OF>( pub fn with_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
fuzzer: &mut Z, fuzzer: &mut Z,
@ -175,11 +173,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, F, OF>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -206,7 +203,7 @@ where
I: Input, I: Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<F, OF>( pub fn generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
observers: OT, observers: OT,
@ -216,11 +213,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic::<F, OF>( Self::with_timeout_generic::<OF>(
user_hooks, user_hooks,
harness_fn, harness_fn,
observers, observers,
@ -239,7 +235,7 @@ where
/// * `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 with_timeout_generic<F, OF>( pub fn with_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
observers: OT, observers: OT,
@ -250,11 +246,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, F, OF>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout, user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?; )?;
@ -317,7 +312,7 @@ impl<EM, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
#[inline] #[inline]
/// Save state if it is an objective /// Save state if it is an objective
pub fn run_observers_and_save_state<E, EM, F, I, OF, S, Z>( pub fn run_observers_and_save_state<E, EM, I, OF, S, Z>(
executor: &mut E, executor: &mut E,
state: &mut S, state: &mut S,
input: &I, input: &I,
@ -329,9 +324,8 @@ pub fn run_observers_and_save_state<E, EM, F, I, OF, S, Z>(
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
F: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
log::info!("in crash handler!"); log::info!("in crash handler!");
@ -341,52 +335,6 @@ pub fn run_observers_and_save_state<E, EM, F, I, OF, S, Z>(
.post_exec_all(state, input, &exitkind) .post_exec_all(state, input, &exitkind)
.expect("Observers post_exec_all failed"); .expect("Observers post_exec_all failed");
let is_corpus = fuzzer
.feedback_mut()
.is_interesting(state, event_mgr, input, &*observers, &exitkind)
.expect("In run_observers_and_save_state feedback failure");
if is_corpus {
// Add the input to the main corpus
let mut testcase = Testcase::from(input.clone());
#[cfg(feature = "track_hit_feedbacks")]
fuzzer
.feedback_mut()
.append_hit_feedbacks(testcase.hit_feedbacks_mut())
.expect("Failed to append hit feedbacks");
testcase.set_parent_id_optional(*state.corpus().current());
fuzzer
.feedback_mut()
.append_metadata(state, event_mgr, &observers, &mut testcase)
.expect("Failed to append metadata");
let id = state
.corpus_mut()
.add(testcase)
.expect("In run_observers_and_save_state failed to add to corpus.");
fuzzer
.scheduler_mut()
.on_add(state, id)
.expect("In run_observers_and_save_state failed to add to scheduler.");
event_mgr
.fire(
state,
Event::NewTestcase {
input: input.clone(),
observers_buf: None, // idk it's not effective anyway just leave it like this
exit_kind: ExitKind::Ok,
corpus_size: state.corpus().count(),
client_config: event_mgr.configuration(),
time: libafl_bolts::current_time(),
forward_id: None,
#[cfg(all(unix, feature = "std", feature = "multi_machine"))]
node_id: None,
},
)
.expect("Could not send off events in run_observers_and_save_state");
}
let is_solution = fuzzer let is_solution = fuzzer
.objective_mut() .objective_mut()
.is_interesting(state, event_mgr, input, &*observers, &exitkind) .is_interesting(state, event_mgr, input, &*observers, &exitkind)
@ -438,7 +386,7 @@ mod tests {
feedbacks::CrashFeedback, feedbacks::CrashFeedback,
inputs::NopInput, inputs::NopInput,
schedulers::RandScheduler, schedulers::RandScheduler,
state::StdState, state::{NopState, StdState},
}; };
#[test] #[test]
@ -449,7 +397,7 @@ mod tests {
let solutions = InMemoryCorpus::new(); let solutions = InMemoryCorpus::new();
let mut objective = CrashFeedback::new(); let mut objective = CrashFeedback::new();
let mut feedback = tuple_list!(); let mut feedback = tuple_list!();
let sche = RandScheduler::new(); let sche: RandScheduler<NopState<NopInput>> = RandScheduler::new();
let mut mgr = NopEventManager::new(); let mut mgr = NopEventManager::new();
let mut state = let mut state =
StdState::new(rand, corpus, solutions, &mut feedback, &mut objective).unwrap(); StdState::new(rand, corpus, solutions, &mut feedback, &mut objective).unwrap();

View File

@ -11,7 +11,7 @@ use core::{
use libafl_bolts::tuples::{RefIndexable, tuple_list}; use libafl_bolts::tuples::{RefIndexable, tuple_list};
use crate::{ use crate::{
Error, HasFeedback, Error,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, Executor, ExitKind, HasObservers,
@ -19,7 +19,7 @@ use crate::{
inprocess::{GenericInProcessExecutorInner, HasInProcessHooks}, inprocess::{GenericInProcessExecutorInner, HasInProcessHooks},
}, },
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::{HasObjective, HasScheduler}, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
state::{HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCurrentTestcase, HasExecutions, HasSolutions},
@ -131,7 +131,7 @@ where
I: Clone + Input, I: Clone + Input,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn new<F, OF>( pub fn new<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
exposed_executor_state: ES, exposed_executor_state: ES,
observers: OT, observers: OT,
@ -141,9 +141,8 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic( Self::with_timeout_generic(
tuple_list!(), tuple_list!(),
@ -165,7 +164,7 @@ where
/// * `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 with_timeout<F, OF>( pub fn with_timeout<OF>(
harness_fn: &'a mut H, harness_fn: &'a mut H,
exposed_executor_state: ES, exposed_executor_state: ES,
observers: OT, observers: OT,
@ -176,11 +175,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, F, OF>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(), tuple_list!(),
observers, observers,
fuzzer, fuzzer,
@ -223,7 +221,7 @@ where
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{ {
/// Create a new in mem executor with the default timeout (5 sec) /// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<F, OF>( pub fn generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
exposed_executor_state: ES, exposed_executor_state: ES,
@ -234,9 +232,8 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
Self::with_timeout_generic( Self::with_timeout_generic(
user_hooks, user_hooks,
@ -259,7 +256,7 @@ where
/// ///
/// This may return an error on unix, if signal handler setup fails /// This may return an error on unix, if signal handler setup fails
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn with_timeout_generic<F, OF>( pub fn with_timeout_generic<OF>(
user_hooks: HT, user_hooks: HT,
harness_fn: HB, harness_fn: HB,
exposed_executor_state: ES, exposed_executor_state: ES,
@ -271,11 +268,10 @@ where
) -> Result<Self, Error> ) -> Result<Self, Error>
where where
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, F, OF>( let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout, user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?; )?;

View File

@ -191,7 +191,7 @@ pub trait Evaluator<E, EM, I, S> {
executor: &mut E, executor: &mut E,
manager: &mut EM, manager: &mut EM,
input: I, input: I,
) -> Result<(CorpusId, ExecuteInputResult), Error>; ) -> Result<CorpusId, Error>;
/// Adds the input to the corpus as a disabled input. /// Adds the input to the corpus as a disabled input.
/// Used during initial corpus loading. /// Used during initial corpus loading.
@ -248,44 +248,15 @@ pub trait Fuzzer<E, EM, I, S, ST> {
) -> Result<CorpusId, Error>; ) -> Result<CorpusId, Error>;
} }
/// The corpus this input should be added to /// The result of harness execution
#[derive(Debug, PartialEq, Eq, Default)] #[derive(Debug, PartialEq, Eq)]
pub struct ExecuteInputResult { pub enum ExecuteInputResult {
is_corpus: bool, /// No special input
is_solution: bool, None,
} /// This input should be stored in the corpus
Corpus,
impl ExecuteInputResult { /// This input leads to a solution
/// Constructor Solution,
#[must_use]
pub fn new(is_corpus: bool, is_solution: bool) -> Self {
Self {
is_corpus,
is_solution,
}
}
/// if this is corpus worthy
#[must_use]
pub fn is_corpus(&self) -> bool {
self.is_corpus
}
/// if this is solution worthy
#[must_use]
pub fn is_solution(&self) -> bool {
self.is_solution
}
/// tell that this is corpus
pub fn set_is_corpus(&mut self, v: bool) {
self.is_corpus = v;
}
/// tell that this is solution
pub fn set_is_solution(&mut self, v: bool) {
self.is_solution = v;
}
} }
/// Your default fuzzer instance, for everyday use. /// Your default fuzzer instance, for everyday use.
@ -368,7 +339,7 @@ where
observers: &OT, observers: &OT,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<ExecuteInputResult, Error> { ) -> Result<ExecuteInputResult, Error> {
let mut res = ExecuteInputResult::default(); let mut res = ExecuteInputResult::None;
#[cfg(not(feature = "introspection"))] #[cfg(not(feature = "introspection"))]
let is_solution = self let is_solution = self
@ -381,9 +352,8 @@ where
.is_interesting_introspection(state, manager, input, observers, exit_kind)?; .is_interesting_introspection(state, manager, input, observers, exit_kind)?;
if is_solution { if is_solution {
res.set_is_solution(true); res = ExecuteInputResult::Solution;
} } else {
#[cfg(not(feature = "introspection"))] #[cfg(not(feature = "introspection"))]
let corpus_worthy = self let corpus_worthy = self
.feedback_mut() .feedback_mut()
@ -394,7 +364,8 @@ where
.is_interesting_introspection(state, manager, input, observers, exit_kind)?; .is_interesting_introspection(state, manager, input, observers, exit_kind)?;
if corpus_worthy { if corpus_worthy {
res.set_is_corpus(true); res = ExecuteInputResult::Corpus;
}
} }
Ok(res) Ok(res)
@ -410,7 +381,10 @@ where
exec_res: &ExecuteInputResult, exec_res: &ExecuteInputResult,
observers: &OT, observers: &OT,
) -> Result<Option<CorpusId>, Error> { ) -> Result<Option<CorpusId>, Error> {
let corpus = if exec_res.is_corpus() { match exec_res {
ExecuteInputResult::None => Ok(None),
ExecuteInputResult::Corpus => {
// Not a solution
// Add the input to the main corpus // Add the input to the main corpus
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
#[cfg(feature = "track_hit_feedbacks")] #[cfg(feature = "track_hit_feedbacks")]
@ -420,12 +394,10 @@ where
.append_metadata(state, manager, observers, &mut testcase)?; .append_metadata(state, manager, observers, &mut testcase)?;
let id = state.corpus_mut().add(testcase)?; let id = state.corpus_mut().add(testcase)?;
self.scheduler_mut().on_add(state, id)?; self.scheduler_mut().on_add(state, id)?;
Ok(Some(id))
} else {
Ok(None)
};
if exec_res.is_solution() { Ok(Some(id))
}
ExecuteInputResult::Solution => {
// The input is a solution, add it to the respective corpus // The input is a solution, add it to the respective corpus
let mut testcase = Testcase::from(input.clone()); let mut testcase = Testcase::from(input.clone());
testcase.set_parent_id_optional(*state.corpus().current()); testcase.set_parent_id_optional(*state.corpus().current());
@ -438,8 +410,10 @@ where
self.objective_mut() self.objective_mut()
.append_metadata(state, manager, observers, &mut testcase)?; .append_metadata(state, manager, observers, &mut testcase)?;
state.solutions_mut().add(testcase)?; state.solutions_mut().add(testcase)?;
Ok(None)
}
} }
corpus
} }
fn serialize_and_dispatch( fn serialize_and_dispatch(
@ -452,14 +426,20 @@ where
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Now send off the event // Now send off the event
let observers_buf = if exec_res.is_corpus() let observers_buf = match exec_res {
&& manager.should_send() ExecuteInputResult::Corpus => {
&& manager.configuration() != EventConfig::AlwaysUnique if manager.should_send() {
{
// TODO set None for fast targets // TODO set None for fast targets
if manager.configuration() == EventConfig::AlwaysUnique {
None
} else {
Some(postcard::to_allocvec(observers)?) Some(postcard::to_allocvec(observers)?)
}
} else { } else {
None None
}
}
_ => None,
}; };
self.dispatch_event(state, manager, input, exec_res, observers_buf, exit_kind)?; self.dispatch_event(state, manager, input, exec_res, observers_buf, exit_kind)?;
@ -476,8 +456,10 @@ where
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Now send off the event // Now send off the event
match exec_res {
ExecuteInputResult::Corpus => {
if manager.should_send() { if manager.should_send() {
if exec_res.is_corpus() {
manager.fire( manager.fire(
state, state,
Event::NewTestcase { Event::NewTestcase {
@ -493,7 +475,9 @@ where
}, },
)?; )?;
} }
if exec_res.is_solution() { }
ExecuteInputResult::Solution => {
if manager.should_send() {
manager.fire( manager.fire(
state, state,
Event::Objective { Event::Objective {
@ -504,7 +488,8 @@ where
)?; )?;
} }
} }
ExecuteInputResult::None => (),
}
Ok(()) Ok(())
} }
@ -522,7 +507,7 @@ where
if send_events { if send_events {
self.serialize_and_dispatch(state, manager, input, &exec_res, observers, exit_kind)?; self.serialize_and_dispatch(state, manager, input, &exec_res, observers, exit_kind)?;
} }
if exec_res.is_corpus() || exec_res.is_solution() { if exec_res != ExecuteInputResult::None {
*state.last_found_time_mut() = current_time(); *state.last_found_time_mut() = current_time();
} }
Ok((exec_res, corpus_id)) Ok((exec_res, corpus_id))
@ -629,7 +614,7 @@ where
if self.input_filter.should_execute(input) { if self.input_filter.should_execute(input) {
self.evaluate_input(state, executor, manager, input) self.evaluate_input(state, executor, manager, input)
} else { } else {
Ok((ExecuteInputResult::default(), None)) Ok((ExecuteInputResult::None, None))
} }
} }
@ -652,7 +637,7 @@ where
executor: &mut E, executor: &mut E,
manager: &mut EM, manager: &mut EM,
input: I, input: I,
) -> Result<(CorpusId, ExecuteInputResult), Error> { ) -> Result<CorpusId, Error> {
*state.last_found_time_mut() = current_time(); *state.last_found_time_mut() = current_time();
let exit_kind = self.execute_input(state, executor, manager, &input)?; let exit_kind = self.execute_input(state, executor, manager, &input)?;
@ -682,7 +667,7 @@ where
self.objective_mut() self.objective_mut()
.append_metadata(state, manager, &*observers, &mut testcase)?; .append_metadata(state, manager, &*observers, &mut testcase)?;
// we don't care about solution id // we don't care about solution id
let _ = state.solutions_mut().add(testcase.clone())?; let id = state.solutions_mut().add(testcase)?;
manager.fire( manager.fire(
state, state,
@ -692,17 +677,22 @@ where
time: current_time(), time: current_time(),
}, },
)?; )?;
// if it is a solution then early return
return Ok(id);
} }
// not a solution
// several is_interesting implementations collect some data about the run, later used in // several is_interesting implementations collect some data about the run, later used in
// append_metadata; we *must* invoke is_interesting here to collect it // append_metadata; we *must* invoke is_interesting here to collect it
#[cfg(not(feature = "introspection"))] #[cfg(not(feature = "introspection"))]
let corpus_worthy = let _is_corpus =
self.feedback_mut() self.feedback_mut()
.is_interesting(state, manager, &input, &*observers, &exit_kind)?; .is_interesting(state, manager, &input, &*observers, &exit_kind)?;
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
let corpus_worthy = self.feedback_mut().is_interesting_introspection( let _is_corpus = self.feedback_mut().is_interesting_introspection(
state, state,
manager, manager,
&input, &input,
@ -738,7 +728,7 @@ where
node_id: None, node_id: None,
}, },
)?; )?;
Ok((id, ExecuteInputResult::new(corpus_worthy, is_solution))) Ok(id)
} }
fn add_disabled_input(&mut self, state: &mut S, input: I) -> Result<CorpusId, Error> { fn add_disabled_input(&mut self, state: &mut S, input: I) -> Result<CorpusId, Error> {

View File

@ -26,8 +26,6 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned};
mod stack; mod stack;
pub use stack::StageStack; pub use stack::StageStack;
#[cfg(feature = "std")]
use crate::fuzzer::ExecuteInputResult;
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
use crate::monitors::stats::ClientPerfStats; use crate::monitors::stats::ClientPerfStats;
use crate::{ use crate::{
@ -35,7 +33,7 @@ use crate::{
corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase}, corpus::{Corpus, CorpusId, HasCurrentCorpusId, HasTestcase, InMemoryCorpus, Testcase},
events::{Event, EventFirer, LogSeverity}, events::{Event, EventFirer, LogSeverity},
feedbacks::StateInitializer, feedbacks::StateInitializer,
fuzzer::Evaluator, fuzzer::{Evaluator, ExecuteInputResult},
generators::Generator, generators::Generator,
inputs::{Input, NopInput}, inputs::{Input, NopInput},
stages::StageId, stages::StageId,
@ -717,15 +715,15 @@ where
Ok(input) => input, Ok(input) => input,
Err(err) => { Err(err) => {
log::error!("Skipping input that we could not load from {path:?}: {err:?}"); log::error!("Skipping input that we could not load from {path:?}: {err:?}");
return Ok(ExecuteInputResult::default()); return Ok(ExecuteInputResult::None);
} }
}; };
if config.forced { if config.forced {
let (_id, result) = fuzzer.add_input(self, executor, manager, input)?; let _: CorpusId = fuzzer.add_input(self, executor, manager, input)?;
Ok(result) Ok(ExecuteInputResult::Corpus)
} else { } else {
let (res, _) = fuzzer.evaluate_input(self, executor, manager, &input)?; let (res, _) = fuzzer.evaluate_input(self, executor, manager, &input)?;
if !(res.is_corpus() || res.is_solution()) { if res == ExecuteInputResult::None {
fuzzer.add_disabled_input(self, input)?; fuzzer.add_disabled_input(self, input)?;
log::warn!("input {:?} was not interesting, adding as disabled.", &path); log::warn!("input {:?} was not interesting, adding as disabled.", &path);
} }
@ -750,7 +748,7 @@ where
match self.next_file() { match self.next_file() {
Ok(path) => { Ok(path) => {
let res = self.load_file(&path, manager, fuzzer, executor, &mut config)?; let res = self.load_file(&path, manager, fuzzer, executor, &mut config)?;
if config.exit_on_solution && res.is_solution() { if config.exit_on_solution && matches!(res, ExecuteInputResult::Solution) {
return Err(Error::invalid_corpus(format!( return Err(Error::invalid_corpus(format!(
"Input {} resulted in a solution.", "Input {} resulted in a solution.",
path.display() path.display()
@ -1054,11 +1052,11 @@ where
for _ in 0..num { for _ in 0..num {
let input = generator.generate(self)?; let input = generator.generate(self)?;
if forced { if forced {
let (_, _) = fuzzer.add_input(self, executor, manager, input)?; let _: CorpusId = fuzzer.add_input(self, executor, manager, input)?;
added += 1; added += 1;
} else { } else {
let (res, _) = fuzzer.evaluate_input(self, executor, manager, &input)?; let (res, _) = fuzzer.evaluate_input(self, executor, manager, &input)?;
if res.is_corpus() { if res != ExecuteInputResult::None {
added += 1; added += 1;
} }
} }

View File

@ -12,7 +12,7 @@ use std::{ptr, str};
#[cfg(feature = "usermode")] #[cfg(feature = "usermode")]
use libafl::state::HasCorpus; use libafl::state::HasCorpus;
use libafl::{ use libafl::{
Error, ExecutionProcessor, HasScheduler, Error, ExecutionProcessor,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{ executors::{
Executor, ExitKind, HasObservers, Executor, ExitKind, HasObservers,
@ -21,7 +21,7 @@ use libafl::{
inprocess_fork::stateful::StatefulInProcessForkExecutor, inprocess_fork::stateful::StatefulInProcessForkExecutor,
}, },
feedbacks::Feedback, feedbacks::Feedback,
fuzzer::{HasFeedback, HasObjective}, fuzzer::HasObjective,
inputs::Input, inputs::Input,
observers::ObserversTuple, observers::ObserversTuple,
state::{HasCurrentTestcase, HasExecutions, HasSolutions}, state::{HasCurrentTestcase, HasExecutions, HasSolutions},
@ -60,7 +60,7 @@ pub struct QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
/// ///
/// This should be used as a crash handler, and nothing else. /// This should be used as a crash handler, and nothing else.
#[cfg(feature = "usermode")] #[cfg(feature = "usermode")]
pub unsafe fn inproc_qemu_crash_handler<E, EM, ET, F, I, OF, S, Z>( pub unsafe fn inproc_qemu_crash_handler<E, EM, ET, I, OF, S, Z>(
signal: Signal, signal: Signal,
info: &mut siginfo_t, info: &mut siginfo_t,
mut context: Option<&mut ucontext_t>, mut context: Option<&mut ucontext_t>,
@ -70,10 +70,9 @@ pub unsafe fn inproc_qemu_crash_handler<E, EM, ET, F, I, OF, S, Z>(
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I> + Unpin, S: HasExecutions + HasSolutions<I> + HasCorpus<I> + HasCurrentTestcase<I> + Unpin,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone + Unpin, I: Input + Clone + Unpin,
{ {
log::debug!("QEMU signal handler has been triggered (signal {signal})"); log::debug!("QEMU signal handler has been triggered (signal {signal})");
@ -127,7 +126,7 @@ pub unsafe fn inproc_qemu_crash_handler<E, EM, ET, F, I, OF, S, Z>(
log::debug!("Running crash hooks."); log::debug!("Running crash hooks.");
run_target_crash_hooks::<ET, I, S>(signal.into()); run_target_crash_hooks::<ET, I, S>(signal.into());
assert!(unsafe { data.maybe_report_crash::<E, EM, F, I, OF, S, Z>(None) }); assert!(unsafe { data.maybe_report_crash::<E, EM, I, OF, S, Z>(None) });
if let Some(cpu) = qemu.current_cpu() { if let Some(cpu) = qemu.current_cpu() {
eprint!("QEMU Context:\n{}", cpu.display_context()); eprint!("QEMU Context:\n{}", cpu.display_context());
@ -164,7 +163,7 @@ pub(crate) static BREAK_ON_TMOUT: AtomicBool = AtomicBool::new(false);
/// # Safety /// # Safety
/// Can call through the `unix_signal_handler::inproc_timeout_handler`. /// Can call through the `unix_signal_handler::inproc_timeout_handler`.
/// Calling this method multiple times concurrently can lead to race conditions. /// Calling this method multiple times concurrently can lead to race conditions.
pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, F, I, OF, S, Z>( pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, I, OF, S, Z>(
signal: Signal, signal: Signal,
info: &mut siginfo_t, info: &mut siginfo_t,
context: Option<&mut ucontext_t>, context: Option<&mut ucontext_t>,
@ -174,12 +173,11 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, F, I, OF, S, Z>(
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
ET: EmulatorModuleTuple<I, S>, ET: EmulatorModuleTuple<I, S>,
F: Feedback<EM, I, E::Observers, S>,
I: Unpin, I: Unpin,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + Unpin + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + Unpin + HasCurrentTestcase<I>,
I: Input, I: Input,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
{ {
#[cfg(feature = "systemmode")] #[cfg(feature = "systemmode")]
unsafe { unsafe {
@ -189,7 +187,6 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, F, I, OF, S, Z>(
libafl::executors::hooks::unix::unix_signal_handler::inproc_timeout_handler::< libafl::executors::hooks::unix::unix_signal_handler::inproc_timeout_handler::<
E, E,
EM, EM,
F,
I, I,
OF, OF,
S, S,
@ -208,7 +205,6 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, F, I, OF, S, Z>(
libafl::executors::hooks::unix::unix_signal_handler::inproc_timeout_handler::< libafl::executors::hooks::unix::unix_signal_handler::inproc_timeout_handler::<
E, E,
EM, EM,
F,
I, I,
OF, OF,
S, S,
@ -238,7 +234,7 @@ where
OT: ObserversTuple<I, S>, OT: ObserversTuple<I, S>,
S: Unpin + HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: Unpin + HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{ {
pub fn new<F, OF>( pub fn new<OF>(
emulator: Emulator<C, CM, ED, ET, I, S, SM>, emulator: Emulator<C, CM, ED, ET, I, S, SM>,
harness_fn: &'a mut H, harness_fn: &'a mut H,
observers: OT, observers: OT,
@ -252,12 +248,8 @@ where
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>, CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
ED: EmulatorDriver<C, CM, ET, I, S, SM>, ED: EmulatorDriver<C, CM, ET, I, S, SM>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, OT, S>,
OF: Feedback<EM, I, OT, S>, OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF> Z: HasObjective<Objective = OF> + ExecutionProcessor<EM, I, OT, S>,
+ HasScheduler<I, S>
+ ExecutionProcessor<EM, I, OT, S>
+ HasFeedback<Feedback = F>,
{ {
let mut inner = StatefulInProcessExecutor::with_timeout( let mut inner = StatefulInProcessExecutor::with_timeout(
harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout, harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout,
@ -267,7 +259,7 @@ where
#[cfg(feature = "usermode")] #[cfg(feature = "usermode")]
{ {
inner.inprocess_hooks_mut().crash_handler = inner.inprocess_hooks_mut().crash_handler =
inproc_qemu_crash_handler::<Self, EM, ET, F, I, OF, S, Z> as *const c_void; inproc_qemu_crash_handler::<Self, EM, ET, I, OF, S, Z> as *const c_void;
} }
// rewrite the timeout handler pointer // rewrite the timeout handler pointer
@ -275,7 +267,6 @@ where
StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>, StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
EM, EM,
ET, ET,
F,
I, I,
OF, OF,
S, S,

View File

@ -1,7 +1,7 @@
//! Setup asan death callbback //! Setup asan death callbback
use libafl::{ use libafl::{
HasFeedback, HasObjective, HasScheduler, HasObjective,
events::{EventFirer, EventRestarter}, events::{EventFirer, EventRestarter},
executors::{Executor, HasObservers, hooks::windows::windows_asan_handler::asan_death_handler}, executors::{Executor, HasObservers, hooks::windows::windows_asan_handler::asan_death_handler},
feedbacks::Feedback, feedbacks::Feedback,
@ -29,7 +29,7 @@ unsafe extern "C" {
/// ///
/// # Safety /// # Safety
/// Calls the unsafe `__sanitizer_set_death_callback` symbol, but should be safe to call otherwise. /// Calls the unsafe `__sanitizer_set_death_callback` symbol, but should be safe to call otherwise.
pub unsafe fn setup_asan_callback<E, EM, F, I, OF, S, Z>( pub unsafe fn setup_asan_callback<E, EM, I, OF, S, Z>(
_executor: &E, _executor: &E,
_event_mgr: &EM, _event_mgr: &EM,
_fuzzer: &Z, _fuzzer: &Z,
@ -37,13 +37,12 @@ pub unsafe fn setup_asan_callback<E, EM, F, I, OF, S, Z>(
E: Executor<EM, I, S, Z> + HasObservers, E: Executor<EM, I, S, Z> + HasObservers,
E::Observers: ObserversTuple<I, S>, E::Observers: ObserversTuple<I, S>,
EM: EventFirer<I, S> + EventRestarter<S>, EM: EventFirer<I, S> + EventRestarter<S>,
F: Feedback<EM, I, E::Observers, S>,
OF: Feedback<EM, I, E::Observers, S>, OF: Feedback<EM, I, E::Observers, S>,
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>, S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
Z: HasObjective<Objective = OF> + HasFeedback<Feedback = F> + HasScheduler<I, S>, Z: HasObjective<Objective = OF>,
I: Input + Clone, I: Input + Clone,
{ {
unsafe { unsafe {
__sanitizer_set_death_callback(Some(asan_death_handler::<E, EM, F, I, OF, S, Z>)); __sanitizer_set_death_callback(Some(asan_death_handler::<E, EM, I, OF, S, Z>));
} }
} }