Fix QEMU userspace crash handler (#1706)
* Fix QEMU userspace crash handler * no_std
This commit is contained in:
parent
5d83c9399a
commit
517d6962bd
@ -634,6 +634,42 @@ pub fn run_observers_and_save_state<E, EM, OF, Z>(
|
||||
log::info!("Bye!");
|
||||
}
|
||||
|
||||
// TODO remove this after executor refactor and libafl qemu new executor
|
||||
/// Expose a version of the crash handler that can be called from e.g. an emulator
|
||||
#[cfg(any(unix, feature = "std"))]
|
||||
pub fn generic_inproc_crash_handler<E, EM, OF, Z>()
|
||||
where
|
||||
E: Executor<EM, Z> + HasObservers,
|
||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||
OF: Feedback<E::State>,
|
||||
E::State: HasExecutions + HasSolutions + HasCorpus,
|
||||
Z: HasObjective<Objective = OF, State = E::State>,
|
||||
{
|
||||
let data = unsafe { &mut GLOBAL_STATE };
|
||||
let in_handler = data.set_in_handler(true);
|
||||
|
||||
if data.is_valid() {
|
||||
let executor = data.executor_mut::<E>();
|
||||
// disarms timeout in case of TimeoutExecutor
|
||||
executor.post_run_reset();
|
||||
let state = data.state_mut::<E::State>();
|
||||
let event_mgr = data.event_mgr_mut::<EM>();
|
||||
let fuzzer = data.fuzzer_mut::<Z>();
|
||||
let input = data.take_current_input::<<E::State as UsesInput>::Input>();
|
||||
|
||||
run_observers_and_save_state::<E, EM, OF, Z>(
|
||||
executor,
|
||||
state,
|
||||
input,
|
||||
fuzzer,
|
||||
event_mgr,
|
||||
ExitKind::Crash,
|
||||
);
|
||||
}
|
||||
|
||||
data.set_in_handler(in_handler);
|
||||
}
|
||||
|
||||
/// The inprocess executor singal handling code for unix
|
||||
#[cfg(unix)]
|
||||
pub mod unix_signal_handler {
|
||||
|
@ -8,7 +8,7 @@ use which::which;
|
||||
|
||||
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
|
||||
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
|
||||
const QEMU_REVISION: &str = "c105904e6659b3fc90e938438a44254dfe47e1c3";
|
||||
const QEMU_REVISION: &str = "32206d23c33a55c9e519e4ae67038ab27d713a24";
|
||||
|
||||
fn build_dep_check(tools: &[&str]) {
|
||||
for tool in tools {
|
||||
|
@ -59,16 +59,7 @@ where
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
extern "C" {
|
||||
// Original QEMU user signal handler
|
||||
fn libafl_qemu_handle_crash(signal: i32, info: *mut siginfo_t, puc: *mut c_void) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
static mut USE_LIBAFL_CRASH_HANDLER: bool = false;
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libafl_executor_reinstall_handlers() {
|
||||
USE_LIBAFL_CRASH_HANDLER = true;
|
||||
fn libafl_qemu_handle_crash(signal: i32, info: *mut siginfo_t, puc: *mut c_void);
|
||||
}
|
||||
|
||||
#[cfg(emulation_mode = "usermode")]
|
||||
@ -76,7 +67,7 @@ pub unsafe fn inproc_qemu_crash_handler<E, EM, OF, Z>(
|
||||
signal: Signal,
|
||||
info: &mut siginfo_t,
|
||||
mut context: Option<&mut ucontext_t>,
|
||||
data: &mut InProcessExecutorHandlerData,
|
||||
_data: &mut InProcessExecutorHandlerData,
|
||||
) where
|
||||
E: Executor<EM, Z> + HasObservers,
|
||||
EM: EventFirer<State = E::State> + EventRestarter<State = E::State>,
|
||||
@ -84,20 +75,11 @@ pub unsafe fn inproc_qemu_crash_handler<E, EM, OF, Z>(
|
||||
E::State: HasExecutions + HasSolutions + HasCorpus,
|
||||
Z: HasObjective<Objective = OF, State = E::State>,
|
||||
{
|
||||
let real_crash = if USE_LIBAFL_CRASH_HANDLER {
|
||||
true
|
||||
} else {
|
||||
let puc = match &mut context {
|
||||
Some(v) => (*v) as *mut ucontext_t as *mut c_void,
|
||||
None => core::ptr::null_mut(),
|
||||
};
|
||||
libafl_qemu_handle_crash(signal as i32, info, puc) != 0
|
||||
let puc = match &mut context {
|
||||
Some(v) => (*v) as *mut ucontext_t as *mut c_void,
|
||||
None => core::ptr::null_mut(),
|
||||
};
|
||||
if real_crash {
|
||||
libafl::executors::inprocess::unix_signal_handler::inproc_crash_handler::<E, EM, OF, Z>(
|
||||
signal, info, context, data,
|
||||
);
|
||||
}
|
||||
libafl_qemu_handle_crash(signal as i32, info, puc);
|
||||
}
|
||||
|
||||
#[cfg(emulation_mode = "systemmode")]
|
||||
@ -157,6 +139,21 @@ where
|
||||
inner.handlers_mut().crash_handler =
|
||||
inproc_qemu_crash_handler::<InProcessExecutor<'a, H, OT, S>, EM, OF, Z>
|
||||
as *const c_void;
|
||||
|
||||
let handler = |hooks: &mut QemuHooks<QT, S>, host_sig| {
|
||||
eprintln!("Crashed with signal {host_sig}");
|
||||
libafl::executors::inprocess::generic_inproc_crash_handler::<
|
||||
InProcessExecutor<'a, H, OT, S>,
|
||||
EM,
|
||||
OF,
|
||||
Z,
|
||||
>();
|
||||
if let Some(cpu) = hooks.emulator().current_cpu() {
|
||||
eprint!("Context:\n{}", cpu.display_context());
|
||||
}
|
||||
};
|
||||
|
||||
hooks.crash_closure(Box::new(handler));
|
||||
}
|
||||
#[cfg(emulation_mode = "systemmode")]
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user