* 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:
parent
115672904e
commit
f4cb9a827d
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -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,20 +352,20 @@ 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"))]
|
||||||
|
let corpus_worthy = self
|
||||||
|
.feedback_mut()
|
||||||
|
.is_interesting(state, manager, input, observers, exit_kind)?;
|
||||||
|
#[cfg(feature = "introspection")]
|
||||||
|
let corpus_worthy = self
|
||||||
|
.feedback_mut()
|
||||||
|
.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
|
||||||
|
|
||||||
#[cfg(not(feature = "introspection"))]
|
if corpus_worthy {
|
||||||
let corpus_worthy = self
|
res = ExecuteInputResult::Corpus;
|
||||||
.feedback_mut()
|
}
|
||||||
.is_interesting(state, manager, input, observers, exit_kind)?;
|
|
||||||
#[cfg(feature = "introspection")]
|
|
||||||
let corpus_worthy = self
|
|
||||||
.feedback_mut()
|
|
||||||
.is_interesting_introspection(state, manager, input, observers, exit_kind)?;
|
|
||||||
|
|
||||||
if corpus_worthy {
|
|
||||||
res.set_is_corpus(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@ -410,36 +381,39 @@ 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 {
|
||||||
// Add the input to the main corpus
|
ExecuteInputResult::None => Ok(None),
|
||||||
let mut testcase = Testcase::from(input.clone());
|
ExecuteInputResult::Corpus => {
|
||||||
#[cfg(feature = "track_hit_feedbacks")]
|
// Not a solution
|
||||||
self.feedback_mut()
|
// Add the input to the main corpus
|
||||||
.append_hit_feedbacks(testcase.hit_feedbacks_mut())?;
|
let mut testcase = Testcase::from(input.clone());
|
||||||
self.feedback_mut()
|
#[cfg(feature = "track_hit_feedbacks")]
|
||||||
.append_metadata(state, manager, observers, &mut testcase)?;
|
self.feedback_mut()
|
||||||
let id = state.corpus_mut().add(testcase)?;
|
.append_hit_feedbacks(testcase.hit_feedbacks_mut())?;
|
||||||
self.scheduler_mut().on_add(state, id)?;
|
self.feedback_mut()
|
||||||
Ok(Some(id))
|
.append_metadata(state, manager, observers, &mut testcase)?;
|
||||||
} else {
|
let id = state.corpus_mut().add(testcase)?;
|
||||||
Ok(None)
|
self.scheduler_mut().on_add(state, id)?;
|
||||||
};
|
|
||||||
|
|
||||||
if exec_res.is_solution() {
|
Ok(Some(id))
|
||||||
// The input is a solution, add it to the respective corpus
|
}
|
||||||
let mut testcase = Testcase::from(input.clone());
|
ExecuteInputResult::Solution => {
|
||||||
testcase.set_parent_id_optional(*state.corpus().current());
|
// The input is a solution, add it to the respective corpus
|
||||||
if let Ok(mut tc) = state.current_testcase_mut() {
|
let mut testcase = Testcase::from(input.clone());
|
||||||
tc.found_objective();
|
testcase.set_parent_id_optional(*state.corpus().current());
|
||||||
|
if let Ok(mut tc) = state.current_testcase_mut() {
|
||||||
|
tc.found_objective();
|
||||||
|
}
|
||||||
|
#[cfg(feature = "track_hit_feedbacks")]
|
||||||
|
self.objective_mut()
|
||||||
|
.append_hit_feedbacks(testcase.hit_objectives_mut())?;
|
||||||
|
self.objective_mut()
|
||||||
|
.append_metadata(state, manager, observers, &mut testcase)?;
|
||||||
|
state.solutions_mut().add(testcase)?;
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "track_hit_feedbacks")]
|
|
||||||
self.objective_mut()
|
|
||||||
.append_hit_feedbacks(testcase.hit_objectives_mut())?;
|
|
||||||
self.objective_mut()
|
|
||||||
.append_metadata(state, manager, observers, &mut testcase)?;
|
|
||||||
state.solutions_mut().add(testcase)?;
|
|
||||||
}
|
}
|
||||||
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 {
|
||||||
Some(postcard::to_allocvec(observers)?)
|
None
|
||||||
} else {
|
} else {
|
||||||
None
|
Some(postcard::to_allocvec(observers)?)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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,35 +456,40 @@ where
|
|||||||
exit_kind: &ExitKind,
|
exit_kind: &ExitKind,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Now send off the event
|
// Now send off the event
|
||||||
if manager.should_send() {
|
|
||||||
if exec_res.is_corpus() {
|
|
||||||
manager.fire(
|
|
||||||
state,
|
|
||||||
Event::NewTestcase {
|
|
||||||
input: input.clone(),
|
|
||||||
observers_buf,
|
|
||||||
exit_kind: *exit_kind,
|
|
||||||
corpus_size: state.corpus().count(),
|
|
||||||
client_config: manager.configuration(),
|
|
||||||
time: current_time(),
|
|
||||||
forward_id: None,
|
|
||||||
#[cfg(all(unix, feature = "std", feature = "multi_machine"))]
|
|
||||||
node_id: None,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
if exec_res.is_solution() {
|
|
||||||
manager.fire(
|
|
||||||
state,
|
|
||||||
Event::Objective {
|
|
||||||
input: self.share_objectives.then_some(input.clone()),
|
|
||||||
objective_size: state.solutions().count(),
|
|
||||||
time: current_time(),
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
match exec_res {
|
||||||
|
ExecuteInputResult::Corpus => {
|
||||||
|
if manager.should_send() {
|
||||||
|
manager.fire(
|
||||||
|
state,
|
||||||
|
Event::NewTestcase {
|
||||||
|
input: input.clone(),
|
||||||
|
observers_buf,
|
||||||
|
exit_kind: *exit_kind,
|
||||||
|
corpus_size: state.corpus().count(),
|
||||||
|
client_config: manager.configuration(),
|
||||||
|
time: current_time(),
|
||||||
|
forward_id: None,
|
||||||
|
#[cfg(all(unix, feature = "std", feature = "multi_machine"))]
|
||||||
|
node_id: None,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExecuteInputResult::Solution => {
|
||||||
|
if manager.should_send() {
|
||||||
|
manager.fire(
|
||||||
|
state,
|
||||||
|
Event::Objective {
|
||||||
|
input: self.share_objectives.then_some(input.clone()),
|
||||||
|
objective_size: state.solutions().count(),
|
||||||
|
time: current_time(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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> {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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>));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user