@@ -12,6 +12,8 @@ use core::{
1212
1313#[ cfg( all( target_os = "linux" , feature = "std" ) ) ]
1414use libafl_bolts:: current_time;
15+ #[ cfg( all( unix, feature = "std" ) ) ]
16+ use libafl_bolts:: minibsod:: { generate_minibsod_to_vec, BsodInfo } ;
1517#[ cfg( all( unix, feature = "std" , not( miri) ) ) ]
1618use libafl_bolts:: os:: unix_signals:: setup_signal_handler;
1719#[ cfg( all( windows, feature = "std" ) ) ]
@@ -21,15 +23,20 @@ use windows::Win32::System::Threading::{CRITICAL_SECTION, PTP_TIMER};
2123
2224#[ cfg( feature = "std" ) ]
2325use crate :: executors:: hooks:: timer:: TimerStruct ;
24- #[ cfg( all( unix, feature = "std" ) ) ]
25- use crate :: executors:: hooks:: unix:: unix_signal_handler;
2626use crate :: {
2727 events:: { EventFirer , EventRestarter } ,
2828 executors:: { hooks:: ExecutorHook , inprocess:: HasInProcessHooks , Executor , HasObservers } ,
2929 feedbacks:: Feedback ,
3030 state:: { HasExecutions , HasSolutions } ,
3131 Error , HasObjective ,
3232} ;
33+ #[ cfg( all( unix, feature = "std" ) ) ]
34+ use crate :: {
35+ executors:: {
36+ hooks:: unix:: unix_signal_handler, inprocess:: run_observers_and_save_state, ExitKind ,
37+ } ,
38+ state:: HasCorpus ,
39+ } ;
3340#[ cfg( any( unix, windows) ) ]
3441use crate :: { inputs:: Input , observers:: ObserversTuple , state:: HasCurrentTestcase } ;
3542
@@ -386,52 +393,111 @@ unsafe impl Sync for InProcessExecutorHandlerData {}
386393impl InProcessExecutorHandlerData {
387394 /// # Safety
388395 /// Only safe if not called twice and if the executor is not used from another borrow after this.
389- #[ cfg( any ( unix , feature = "std" ) ) ]
396+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
390397 pub ( crate ) unsafe fn executor_mut < ' a , E > ( & self ) -> & ' a mut E {
391398 unsafe { ( self . executor_ptr as * mut E ) . as_mut ( ) . unwrap ( ) }
392399 }
393400
394401 /// # Safety
395402 /// Only safe if not called twice and if the state is not used from another borrow after this.
396- #[ cfg( any ( unix , feature = "std" ) ) ]
403+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
397404 pub ( crate ) unsafe fn state_mut < ' a , S > ( & self ) -> & ' a mut S {
398405 unsafe { ( self . state_ptr as * mut S ) . as_mut ( ) . unwrap ( ) }
399406 }
400407
401408 /// # Safety
402409 /// Only safe if not called twice and if the event manager is not used from another borrow after this.
403- #[ cfg( any ( unix , feature = "std" ) ) ]
410+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
404411 pub ( crate ) unsafe fn event_mgr_mut < ' a , EM > ( & self ) -> & ' a mut EM {
405412 unsafe { ( self . event_mgr_ptr as * mut EM ) . as_mut ( ) . unwrap ( ) }
406413 }
407414
408415 /// # Safety
409416 /// Only safe if not called twice and if the fuzzer is not used from another borrow after this.
410- #[ cfg( any ( unix , feature = "std" ) ) ]
417+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
411418 pub ( crate ) unsafe fn fuzzer_mut < ' a , Z > ( & self ) -> & ' a mut Z {
412419 unsafe { ( self . fuzzer_ptr as * mut Z ) . as_mut ( ) . unwrap ( ) }
413420 }
414421
415422 /// # Safety
416423 /// Only safe if not called concurrently.
417- #[ cfg( any ( unix , feature = "std" ) ) ]
424+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
418425 pub ( crate ) unsafe fn take_current_input < ' a , I > ( & mut self ) -> & ' a I {
419426 let r = unsafe { ( self . current_input_ptr as * const I ) . as_ref ( ) . unwrap ( ) } ;
420427 self . current_input_ptr = ptr:: null ( ) ;
421428 r
422429 }
423430
424- #[ cfg( any ( unix , feature = "std" ) ) ]
431+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
425432 pub ( crate ) fn is_valid ( & self ) -> bool {
426433 !self . current_input_ptr . is_null ( )
427434 }
428435
429- #[ cfg( any ( unix , feature = "std" ) ) ]
436+ #[ cfg( all ( feature = "std" , any ( unix , windows ) ) ) ]
430437 pub ( crate ) fn set_in_handler ( & mut self , v : bool ) -> bool {
431438 let old = self . in_handler ;
432439 self . in_handler = v;
433440 old
434441 }
442+
443+ /// if data is valid, safely report a crash and return true.
444+ /// return false otherwise.
445+ ///
446+ /// # Safety
447+ ///
448+ /// Should only be called to signal a crash in the target
449+ #[ cfg( all( unix, feature = "std" ) ) ]
450+ pub unsafe fn maybe_report_crash < E , EM , I , OF , S , Z > (
451+ & mut self ,
452+ bsod_info : Option < BsodInfo > ,
453+ ) -> bool
454+ where
455+ E : Executor < EM , I , S , Z > + HasObservers ,
456+ E :: Observers : ObserversTuple < I , S > ,
457+ EM : EventFirer < I , S > + EventRestarter < S > ,
458+ OF : Feedback < EM , I , E :: Observers , S > ,
459+ S : HasExecutions + HasSolutions < I > + HasCorpus < I > + HasCurrentTestcase < I > ,
460+ Z : HasObjective < Objective = OF > ,
461+ I : Input + Clone ,
462+ {
463+ if self . is_valid ( ) {
464+ let executor = self . executor_mut :: < E > ( ) ;
465+ // disarms timeout in case of timeout
466+ let state = self . state_mut :: < S > ( ) ;
467+ let event_mgr = self . event_mgr_mut :: < EM > ( ) ;
468+ let fuzzer = self . fuzzer_mut :: < Z > ( ) ;
469+ let input = self . take_current_input :: < I > ( ) ;
470+
471+ log:: error!( "Target crashed!" ) ;
472+
473+ if let Some ( bsod_info) = bsod_info {
474+ let bsod = generate_minibsod_to_vec (
475+ bsod_info. signal ,
476+ & bsod_info. siginfo ,
477+ bsod_info. ucontext . as_ref ( ) ,
478+ ) ;
479+
480+ if let Ok ( bsod) = bsod {
481+ if let Ok ( r) = std:: str:: from_utf8 ( & bsod) {
482+ log:: error!( "{}" , r) ;
483+ }
484+ }
485+ }
486+
487+ run_observers_and_save_state :: < E , EM , I , OF , S , Z > (
488+ executor,
489+ state,
490+ input,
491+ fuzzer,
492+ event_mgr,
493+ ExitKind :: Crash ,
494+ ) ;
495+
496+ return true ;
497+ }
498+
499+ false
500+ }
435501}
436502
437503/// Exception handling needs some nasty unsafe.
0 commit comments