Fix Frida CI for Windows, Clippy (#1430)

* Fix Frida for Windows

* more fix

* clippy in pthreads
This commit is contained in:
Dominik Maier 2023-08-20 13:30:21 +02:00 committed by GitHub
parent c6bfb07832
commit c31ca2c9f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 59 deletions

View File

@ -17,8 +17,8 @@ use libafl::{
corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus}, corpus::{CachedOnDiskCorpus, Corpus, OnDiskCorpus},
events::{launcher::Launcher, llmp::LlmpRestartingEventManager, EventConfig}, events::{launcher::Launcher, llmp::LlmpRestartingEventManager, EventConfig},
executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor}, executors::{inprocess::InProcessExecutor, ExitKind, ShadowExecutor},
feedback_and_fast, feedback_or, feedback_or_fast, feedback_or, feedback_or_fast,
feedbacks::{ConstFeedback, CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer}, fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes}, inputs::{BytesInput, HasTargetBytes},
monitors::MultiMonitor, monitors::MultiMonitor,
@ -32,6 +32,8 @@ use libafl::{
state::{HasCorpus, HasMetadata, StdState}, state::{HasCorpus, HasMetadata, StdState},
Error, Error,
}; };
#[cfg(unix)]
use libafl::{feedback_and_fast, feedbacks::ConstFeedback};
use libafl_bolts::{ use libafl_bolts::{
cli::{parse_args, FuzzerOptions}, cli::{parse_args, FuzzerOptions},
current_nanos, current_nanos,

View File

@ -1,5 +1,5 @@
use core::fmt::{self, Debug, Formatter}; use core::fmt::{self, Debug, Formatter};
use std::{ffi::c_void, marker::PhantomData, process}; use std::{ffi::c_void, marker::PhantomData};
use frida_gum::{ use frida_gum::{
stalker::{NoneEventSink, Stalker}, stalker::{NoneEventSink, Stalker},
@ -35,7 +35,7 @@ where
{ {
base: InProcessExecutor<'a, H, OT, S>, base: InProcessExecutor<'a, H, OT, S>,
// thread_id for the Stalker // thread_id for the Stalker
thread_id: u32, thread_id: Option<u32>,
/// Frida's dynamic rewriting engine /// Frida's dynamic rewriting engine
stalker: Stalker<'a>, stalker: Stalker<'a>,
/// User provided callback for instrumentation /// User provided callback for instrumentation
@ -87,11 +87,15 @@ where
} else { } else {
self.followed = true; self.followed = true;
let transformer = self.helper.transformer(); let transformer = self.helper.transformer();
self.stalker.follow::<NoneEventSink>( if let Some(thread_id) = self.thread_id {
self.thread_id.try_into().unwrap(), self.stalker.follow::<NoneEventSink>(
transformer, thread_id.try_into().unwrap(),
None, transformer,
); None,
);
} else {
self.stalker.follow_me::<NoneEventSink>(transformer, None);
}
} }
} }
let res = self.base.run_target(fuzzer, state, mgr, input); let res = self.base.run_target(fuzzer, state, mgr, input);
@ -162,7 +166,7 @@ where
base: InProcessExecutor<'a, H, OT, S>, base: InProcessExecutor<'a, H, OT, S>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>, helper: &'c mut FridaInstrumentationHelper<'b, RT>,
) -> Self { ) -> Self {
Self::on_thread(gum, base, helper, process::id()) Self::_on_thread(gum, base, helper, None)
} }
/// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`. /// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`.
@ -171,6 +175,16 @@ where
base: InProcessExecutor<'a, H, OT, S>, base: InProcessExecutor<'a, H, OT, S>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>, helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: u32, thread_id: u32,
) -> Self {
Self::_on_thread(gum, base, helper, Some(thread_id))
}
/// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`, of `thread_id` is provided.
fn _on_thread(
gum: &'a Gum,
base: InProcessExecutor<'a, H, OT, S>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: Option<u32>,
) -> Self { ) -> Self {
let mut stalker = Stalker::new(gum); let mut stalker = Stalker::new(gum);
// Include the current module (the fuzzer) in stalked ranges. We clone the ranges so that // Include the current module (the fuzzer) in stalked ranges. We clone the ranges so that

View File

@ -1,5 +1,4 @@
use std::{ use std::{
cell::UnsafeCell,
convert::{TryFrom, TryInto}, convert::{TryFrom, TryInto},
sync::RwLock, sync::RwLock,
}; };
@ -21,49 +20,43 @@ type pthread_introspection_hook_t = extern "C" fn(
); );
extern "C" { extern "C" {
fn pthread_introspection_hook_install( fn pthread_introspection_hook_install(hook: *const libc::c_void) -> *const libc::c_void;
hook: *const libc::c_void,
) -> pthread_introspection_hook_t;
} }
struct PreviousHook(UnsafeCell<Option<pthread_introspection_hook_t>>); struct PreviousHook(*const pthread_introspection_hook_t);
impl PreviousHook { impl PreviousHook {
/// Dispatch to the previous hook, if it is set. /// Dispatch to the previous hook, if it is set.
pub fn dispatch( pub unsafe fn dispatch(
&self, &self,
event: libc::c_uint, event: libc::c_uint,
thread: libc::pthread_t, thread: libc::pthread_t,
addr: *const libc::c_void, addr: *const libc::c_void,
size: libc::size_t, size: libc::size_t,
) { ) {
let inner = unsafe { *self.0.get() }; let inner = self.0;
if inner.is_none() { if inner.is_null() {
return; return;
} }
let inner = inner.unwrap(); unsafe { (*inner)(event, thread, addr, size) };
inner(event, thread, addr, size);
} }
/// Set the previous hook. /// Set the previous hook.
pub fn set(&self, hook: pthread_introspection_hook_t) { pub fn set(&mut self, hook: *const pthread_introspection_hook_t) {
unsafe { self.0 = hook;
*self.0.get() = Some(hook);
}
} }
/// Ensure the previous hook is installed again. /// Ensure the previous hook is installed again.
pub fn reset(&self) { pub fn reset(&mut self) {
let inner = unsafe { *self.0.get() }; let inner = self.0;
if inner.is_none() { if inner.is_null() {
unsafe { unsafe {
pthread_introspection_hook_install(std::ptr::null()); pthread_introspection_hook_install(std::ptr::null());
} }
return; return;
} }
let inner = inner.unwrap();
unsafe { unsafe {
*self.0.get() = None; self.0 = std::ptr::null();
pthread_introspection_hook_install(inner as *const libc::c_void); pthread_introspection_hook_install(inner as *const libc::c_void);
} }
} }
@ -74,7 +67,7 @@ impl PreviousHook {
unsafe impl Sync for PreviousHook {} unsafe impl Sync for PreviousHook {}
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
static PREVIOUS_HOOK: PreviousHook = PreviousHook(UnsafeCell::new(None)); static mut PREVIOUS_HOOK: PreviousHook = PreviousHook(std::ptr::null());
static CURRENT_HOOK: RwLock<Option<PthreadIntrospectionHook>> = RwLock::new(None); static CURRENT_HOOK: RwLock<Option<PthreadIntrospectionHook>> = RwLock::new(None);
@ -87,7 +80,7 @@ extern "C" fn pthread_introspection_hook(
if let Some(ref hook) = *CURRENT_HOOK.read().unwrap() { if let Some(ref hook) = *CURRENT_HOOK.read().unwrap() {
hook(event.try_into().unwrap(), thread, addr, size); hook(event.try_into().unwrap(), thread, addr, size);
} }
PREVIOUS_HOOK.dispatch(event, thread, addr, size); unsafe { PREVIOUS_HOOK.dispatch(event, thread, addr, size) };
} }
/// Closure type for `pthread_introspection` hooks. /// Closure type for `pthread_introspection` hooks.
@ -153,7 +146,10 @@ impl From<EventType> for libc::c_uint {
/// thread id=0x16bf67000 event=Terminate addr=0x16bd60000 size=208000 /// thread id=0x16bf67000 event=Terminate addr=0x16bd60000 size=208000
/// thread id=0x16bf67000 event=Destroy addr=0x16bf67000 size=4000 /// thread id=0x16bf67000 event=Destroy addr=0x16bf67000 size=4000
/// ``` /// ```
pub fn install<H>(hook: H) ///
/// # Safety
/// Potential data race when if called at the same time as `install` or `reset` from another thread
pub unsafe fn install<H>(hook: H)
where where
H: Fn(EventType, libc::pthread_t, *const libc::c_void, libc::size_t) + Send + Sync + 'static, H: Fn(EventType, libc::pthread_t, *const libc::c_void, libc::size_t) + Send + Sync + 'static,
{ {
@ -165,9 +161,10 @@ where
}; };
// Allow because we're sure this isn't from a different code generation unit. // Allow because we're sure this isn't from a different code generation unit.
#[allow(clippy::fn_address_comparisons, clippy::fn_null_check)] if !(prev).is_null() && prev != pthread_introspection_hook as *const libc::c_void {
if !(prev as *const libc::c_void).is_null() && prev != pthread_introspection_hook { unsafe {
PREVIOUS_HOOK.set(prev); PREVIOUS_HOOK.set(prev as *const pthread_introspection_hook_t);
}
} }
} }
@ -179,8 +176,11 @@ where
///# use std::thread; ///# use std::thread;
/// pthread_hook::reset(); /// pthread_hook::reset();
/// ``` /// ```
pub fn reset() { ///
PREVIOUS_HOOK.reset(); /// # Safety
/// Potential data race when if called at the same time as `install` or `reset` from another thread
pub unsafe fn reset() {
unsafe { PREVIOUS_HOOK.reset() };
} }
/// The following tests fail if they are not run sequentially. /// The following tests fail if they are not run sequentially.
@ -204,7 +204,7 @@ mod test {
}); });
thread::sleep(Duration::from_millis(50)); thread::sleep(Duration::from_millis(50));
super::reset(); unsafe { super::reset() };
assert!(!*triggered.lock().unwrap()); assert!(!*triggered.lock().unwrap());
} }
@ -214,19 +214,21 @@ mod test {
let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false)); let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
let inner_triggered = triggered.clone(); let inner_triggered = triggered.clone();
super::install(move |event, _, _, _| { unsafe {
if event == super::EventType::Create { super::install(move |event, _, _, _| {
let mut triggered = inner_triggered.lock().unwrap(); if event == super::EventType::Create {
*triggered = true; let mut triggered = inner_triggered.lock().unwrap();
} *triggered = true;
}); }
})
};
thread::spawn(|| { thread::spawn(|| {
thread::sleep(Duration::from_millis(1)); thread::sleep(Duration::from_millis(1));
}); });
thread::sleep(Duration::from_millis(50)); thread::sleep(Duration::from_millis(50));
super::reset(); unsafe { super::reset() };
assert!(*triggered.lock().unwrap()); assert!(*triggered.lock().unwrap());
} }
@ -236,19 +238,21 @@ mod test {
let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false)); let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
let inner_triggered = triggered.clone(); let inner_triggered = triggered.clone();
super::install(move |event, _, _, _| { unsafe {
if event == super::EventType::Start { super::install(move |event, _, _, _| {
let mut triggered = inner_triggered.lock().unwrap(); if event == super::EventType::Start {
*triggered = true; let mut triggered = inner_triggered.lock().unwrap();
} *triggered = true;
}); }
})
};
thread::spawn(|| { thread::spawn(|| {
thread::sleep(Duration::from_millis(1)); thread::sleep(Duration::from_millis(1));
}); });
thread::sleep(Duration::from_millis(50)); thread::sleep(Duration::from_millis(50));
super::reset(); unsafe { super::reset() };
assert!(*triggered.lock().unwrap()); assert!(*triggered.lock().unwrap());
} }
@ -258,14 +262,16 @@ mod test {
let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false)); let triggered: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
let inner_triggered = triggered.clone(); let inner_triggered = triggered.clone();
super::install(move |event, _, _, _| { unsafe {
if event == super::EventType::Start { super::install(move |event, _, _, _| {
let mut triggered = inner_triggered.lock().unwrap(); if event == super::EventType::Start {
*triggered = true; let mut triggered = inner_triggered.lock().unwrap();
} *triggered = true;
}); }
})
};
super::reset(); unsafe { super::reset() };
thread::spawn(|| { thread::spawn(|| {
thread::sleep(Duration::from_millis(1)); thread::sleep(Duration::from_millis(1));