From d90d232e7af5a0065698b5260cc262cf7d12de53 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 3 Apr 2024 11:47:09 +0200 Subject: [PATCH] Frida: Move ASAN_ERRORS values into a Mutex for shared access (#1995) * Move ASAN_ERRORS values into a Mutex for shared access * Fix frida doc * oops * clippy --- docs/src/advanced_features/frida.md | 2 +- libafl_frida/src/alloc.rs | 6 +- libafl_frida/src/asan/asan_rt.rs | 24 ++--- libafl_frida/src/asan/errors.rs | 144 +++++++++++++++------------- libafl_frida/src/asan/hook_funcs.rs | 118 +++++++++++------------ libafl_frida/src/executor.rs | 14 +-- 6 files changed, 157 insertions(+), 151 deletions(-) diff --git a/docs/src/advanced_features/frida.md b/docs/src/advanced_features/frida.md index b538a99b0b..5d1532de9f 100644 --- a/docs/src/advanced_features/frida.md +++ b/docs/src/advanced_features/frida.md @@ -73,7 +73,7 @@ You can then link this observer to `FridaInProcessExecutor` as follows: tuple_list!( edges_observer, time_observer, - AsanErrorsObserver::new(addr_of!(ASAN_ERRORS)) + AsanErrorsObserver::from_static_asan_errors() ), &mut fuzzer, &mut state, diff --git a/libafl_frida/src/alloc.rs b/libafl_frida/src/alloc.rs index d546613749..0f8fca910b 100644 --- a/libafl_frida/src/alloc.rs +++ b/libafl_frida/src/alloc.rs @@ -244,14 +244,14 @@ impl Allocator { //log::trace!("freeing address: {:?}", ptr); let Some(metadata) = self.allocations.get_mut(&(ptr as usize)) else { if !ptr.is_null() { - AsanErrors::get_mut() + AsanErrors::get_mut_blocking() .report_error(AsanError::UnallocatedFree((ptr as usize, Backtrace::new()))); } return; }; if metadata.freed { - AsanErrors::get_mut().report_error(AsanError::DoubleFree(( + AsanErrors::get_mut_blocking().report_error(AsanError::DoubleFree(( ptr as usize, metadata.clone(), Backtrace::new(), @@ -480,7 +480,7 @@ impl Allocator { pub fn check_for_leaks(&self) { for metadata in self.allocations.values() { if !metadata.freed { - AsanErrors::get_mut() + AsanErrors::get_mut_blocking() .report_error(AsanError::Leak((metadata.address, metadata.clone()))); } } diff --git a/libafl_frida/src/asan/asan_rt.rs b/libafl_frida/src/asan/asan_rt.rs index 0b8b23b2d5..64aa5f4626 100644 --- a/libafl_frida/src/asan/asan_rt.rs +++ b/libafl_frida/src/asan/asan_rt.rs @@ -10,12 +10,7 @@ use core::{ fmt::{self, Debug, Formatter}, ptr::addr_of_mut, }; -use std::{ - ffi::c_void, - num::NonZeroUsize, - ptr::{addr_of, write_volatile}, - rc::Rc, -}; +use std::{ffi::c_void, num::NonZeroUsize, ptr::write_volatile, rc::Rc, sync::MutexGuard}; use backtrace::Backtrace; use dynasmrt::{dynasm, DynasmApi, DynasmLabelApi}; @@ -171,9 +166,7 @@ impl FridaRuntime for AsanRuntime { ) { self.allocator.init(); - unsafe { - ASAN_ERRORS = Some(AsanErrors::new(self.continue_on_error)); - } + AsanErrors::get_mut_blocking().set_continue_on_error(self.continue_on_error); self.generate_instrumentation_blobs(); @@ -340,10 +333,11 @@ impl AsanRuntime { self.allocator.check_for_leaks(); } - /// Returns the `AsanErrors` from the recent run + /// Returns the `AsanErrors` from the recent run. + /// Will block if some other thread holds on to the `ASAN_ERRORS` Mutex. #[allow(clippy::unused_self)] - pub fn errors(&mut self) -> &Option { - unsafe { &*addr_of!(ASAN_ERRORS) } + pub fn errors(&mut self) -> MutexGuard<'static, AsanErrors> { + ASAN_ERRORS.lock().unwrap() } /// Make sure the specified memory is unpoisoned @@ -1085,11 +1079,11 @@ impl AsanRuntime { backtrace, )) }; - AsanErrors::get_mut().report_error(error); + AsanErrors::get_mut_blocking().report_error(error); // This is not even a mem instruction?? } else { - AsanErrors::get_mut().report_error(AsanError::Unknown(( + AsanErrors::get_mut_blocking().report_error(AsanError::Unknown(( self.regs, actual_pc, (None, None, 0, fault_address), @@ -1223,7 +1217,7 @@ impl AsanRuntime { backtrace, )) }; - AsanErrors::get_mut().report_error(error); + AsanErrors::get_mut_blocking().report_error(error); } #[cfg(target_arch = "x86_64")] diff --git a/libafl_frida/src/asan/errors.rs b/libafl_frida/src/asan/errors.rs index ae825500d8..95def5a33b 100644 --- a/libafl_frida/src/asan/errors.rs +++ b/libafl_frida/src/asan/errors.rs @@ -1,5 +1,10 @@ //! Errors that can be caught by the `libafl_frida` address sanitizer. -use std::{fmt::Debug, io::Write, marker::PhantomData, ptr::addr_of}; +use std::{ + fmt::Debug, + io::Write, + marker::PhantomData, + sync::{Mutex, MutexGuard}, +}; use backtrace::Backtrace; use color_backtrace::{default_output_stream, BacktracePrinter, Verbosity}; @@ -110,7 +115,7 @@ pub struct AsanErrors { impl AsanErrors { /// Creates a new `AsanErrors` struct #[must_use] - pub fn new(continue_on_error: bool) -> Self { + pub const fn new(continue_on_error: bool) -> Self { Self { errors: Vec::new(), continue_on_error, @@ -135,16 +140,18 @@ impl AsanErrors { } /// Get a mutable reference to the global [`struct@AsanErrors`] object - #[must_use] - pub fn get_mut<'a>() -> &'a mut Self { - unsafe { ASAN_ERRORS.as_mut().unwrap() } + pub fn get_mut_blocking() -> MutexGuard<'static, Self> { + ASAN_ERRORS.lock().unwrap() + } + + /// Sets if this [`AsanErrors`] variable should continue on error, or not. + pub fn set_continue_on_error(&mut self, continue_on_error: bool) { + self.continue_on_error = continue_on_error; } /// Report an error #[allow(clippy::too_many_lines)] pub(crate) fn report_error(&mut self, error: AsanError) { - self.errors.push(error.clone()); - let mut out_stream = default_output_stream(); let output = out_stream.as_mut(); @@ -164,11 +171,11 @@ impl AsanErrors { .set_color(ColorSpec::new().set_fg(Some(Color::Red))) .unwrap(); write!(output, "{}", error.description()).unwrap(); - match error { - AsanError::OobRead(mut error) - | AsanError::OobWrite(mut error) - | AsanError::ReadAfterFree(mut error) - | AsanError::WriteAfterFree(mut error) => { + match &error { + AsanError::OobRead(error) + | AsanError::OobWrite(error) + | AsanError::ReadAfterFree(error) + | AsanError::WriteAfterFree(error) => { let (basereg, indexreg, _displacement, fault_address) = error.fault; if let Some(module_details) = ModuleDetails::with_address(error.pc as u64) { @@ -301,7 +308,11 @@ impl AsanErrors { writeln!(output, "allocation was zero-sized").unwrap(); } - if let Some(backtrace) = error.metadata.allocation_site_backtrace.as_mut() { + let mut allocation_site_backtrace = + error.metadata.allocation_site_backtrace.clone(); + let mut release_site_backtrace = error.metadata.release_site_backtrace.clone(); + + if let Some(backtrace) = &mut allocation_site_backtrace { writeln!(output, "allocation site backtrace:").unwrap(); backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); @@ -310,7 +321,7 @@ impl AsanErrors { if error.metadata.freed { #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " FREE INFO ").unwrap(); - if let Some(backtrace) = error.metadata.release_site_backtrace.as_mut() { + if let Some(backtrace) = &mut release_site_backtrace { writeln!(output, "free site backtrace:").unwrap(); backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); @@ -330,7 +341,7 @@ impl AsanErrors { { let invocation = Interceptor::current_invocation(); let cpu_context = invocation.cpu_context(); - if let Some(module_details) = ModuleDetails::with_address(_pc as u64) { + if let Some(module_details) = ModuleDetails::with_address(*_pc as u64) { writeln!( output, " at 0x{:x} ({}@0x{:04x})", @@ -347,7 +358,7 @@ impl AsanErrors { writeln!(output, "{:━^100}", " REGISTERS ").unwrap(); for reg in 0..29 { let val = cpu_context.reg(reg); - if val as usize == address { + if val as usize == *address { output .set_color(ColorSpec::new().set_fg(Some(Color::Red))) .unwrap(); @@ -363,12 +374,12 @@ impl AsanErrors { writeln!(output, "pc : 0x{:016x} ", cpu_context.pc()).unwrap(); } - backtrace_printer.print_trace(&backtrace, output).unwrap(); + backtrace_printer.print_trace(backtrace, output).unwrap(); } - AsanError::DoubleFree((ptr, mut metadata, backtrace)) => { + AsanError::DoubleFree((ptr, metadata, backtrace)) => { writeln!(output, " of {ptr:?}").unwrap(); output.reset().unwrap(); - backtrace_printer.print_trace(&backtrace, output).unwrap(); + backtrace_printer.print_trace(backtrace, output).unwrap(); #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " ALLOCATION INFO ").unwrap(); @@ -383,14 +394,17 @@ impl AsanErrors { writeln!(output, "allocation was zero-sized").unwrap(); } - if let Some(backtrace) = metadata.allocation_site_backtrace.as_mut() { + let mut allocation_site_backtrace = metadata.allocation_site_backtrace.clone(); + let mut release_site_backtrace = metadata.release_site_backtrace.clone(); + + if let Some(backtrace) = &mut allocation_site_backtrace { writeln!(output, "allocation site backtrace:").unwrap(); backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); } #[allow(clippy::non_ascii_literal)] writeln!(output, "{:━^100}", " FREE INFO ").unwrap(); - if let Some(backtrace) = metadata.release_site_backtrace.as_mut() { + if let Some(backtrace) = &mut release_site_backtrace { writeln!(output, "previous free site backtrace:").unwrap(); backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); @@ -399,9 +413,9 @@ impl AsanErrors { AsanError::UnallocatedFree((ptr, backtrace)) => { writeln!(output, " of {ptr:#016x}").unwrap(); output.reset().unwrap(); - backtrace_printer.print_trace(&backtrace, output).unwrap(); + backtrace_printer.print_trace(backtrace, output).unwrap(); } - AsanError::Leak((ptr, mut metadata)) => { + AsanError::Leak((ptr, metadata)) => { writeln!(output, " of {ptr:#016x}").unwrap(); output.reset().unwrap(); @@ -418,7 +432,9 @@ impl AsanErrors { writeln!(output, "allocation was zero-sized").unwrap(); } - if let Some(backtrace) = metadata.allocation_site_backtrace.as_mut() { + let mut allocation_site_backtrace = metadata.allocation_site_backtrace.clone(); + + if let Some(backtrace) = &mut allocation_site_backtrace { writeln!(output, "allocation site backtrace:").unwrap(); backtrace.resolve(); backtrace_printer.print_trace(backtrace, output).unwrap(); @@ -429,7 +445,7 @@ impl AsanErrors { | AsanError::StackOobWrite((registers, pc, fault, backtrace)) => { let (basereg, indexreg, _displacement, fault_address) = fault; - if let Some(module_details) = ModuleDetails::with_address(pc as u64) { + if let Some(module_details) = ModuleDetails::with_address(*pc as u64) { writeln!( output, " at 0x{:x} ({}:0x{:04x}), faulting address 0x{:x}", @@ -507,20 +523,20 @@ impl AsanErrors { #[cfg(target_arch = "x86_64")] let insts = disas_count( &decoder, - unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 15 * 11) }, + unsafe { std::slice::from_raw_parts(*start_pc as *mut u8, 15 * 11) }, 11, ); #[cfg(target_arch = "aarch64")] let insts = disas_count( &decoder, - unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 4 * 11) }, + unsafe { std::slice::from_raw_parts(*start_pc as *mut u8, 4 * 11) }, 11, ); - let mut inst_address = start_pc; + let mut inst_address = *start_pc; for insn in insts { - if inst_address == pc { + if inst_address == *pc { output .set_color(ColorSpec::new().set_fg(Some(Color::Red))) .unwrap(); @@ -532,10 +548,12 @@ impl AsanErrors { inst_address += insn.len().to_const() as usize; } - backtrace_printer.print_trace(&backtrace, output).unwrap(); + backtrace_printer.print_trace(backtrace, output).unwrap(); } }; + self.errors.push(error); + #[allow(clippy::manual_assert)] if !self.continue_on_error { panic!("ASAN: Crashing target!"); @@ -544,13 +562,16 @@ impl AsanErrors { } /// static field for `AsanErrors` for a run -pub static mut ASAN_ERRORS: Option = None; +pub static ASAN_ERRORS: Mutex = Mutex::new(AsanErrors::new(true)); -/// An observer for frida address sanitizer `AsanError`s for a frida executor run +/// An observer for frida address sanitizer `AsanError`s for a `Frida` executor run #[derive(Debug, Serialize, Deserialize)] #[allow(clippy::unsafe_derive_deserialize)] -pub struct AsanErrorsObserver { - errors: OwnedPtr>, +pub enum AsanErrorsObserver { + /// Observer referencing a list behind a [`OwnedPtr`] pointer. + Ptr(OwnedPtr), + /// Observer referencing the static [`ASAN_ERRORS`] variable. + Static, } impl Observer for AsanErrorsObserver @@ -558,11 +579,7 @@ where S: UsesInput, { fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> { - unsafe { - if ASAN_ERRORS.is_some() { - ASAN_ERRORS.as_mut().unwrap().clear(); - } - } + AsanErrors::get_mut_blocking().clear(); Ok(()) } @@ -578,24 +595,22 @@ impl Named for AsanErrorsObserver { impl AsanErrorsObserver { /// Creates a new [`AsanErrorsObserver`], pointing to a constant `AsanErrors` field #[must_use] - pub fn new(errors: OwnedPtr>) -> Self { - Self { errors } + pub fn new(errors: OwnedPtr) -> Self { + Self::Ptr(errors) } /// Creates a new [`AsanErrorsObserver`], pointing to the [`ASAN_ERRORS`] global static field. /// /// # Safety /// The field should not be accessed multiple times at the same time (i.e., from different threads)! - pub unsafe fn from_static_asan_errors() -> Self { - Self::from_ptr(addr_of!(ASAN_ERRORS)) + pub fn from_static_asan_errors() -> Self { + Self::Static } /// Creates a new `AsanErrorsObserver`, owning the `AsanErrors` #[must_use] - pub fn owned(errors: Option) -> Self { - Self { - errors: OwnedPtr::Owned(Box::new(errors)), - } + pub fn owned(errors: AsanErrors) -> Self { + Self::Ptr(OwnedPtr::Owned(Box::new(errors))) } /// Creates a new `AsanErrorsObserver` from a raw ptr @@ -604,18 +619,19 @@ impl AsanErrorsObserver { /// Will dereference this pointer at a later point in time. /// The pointer *must* outlive this [`AsanErrorsObserver`]'s lifetime. #[must_use] - pub unsafe fn from_ptr(errors: *const Option) -> Self { - Self { - errors: OwnedPtr::Ptr(errors), - } + pub unsafe fn from_ptr(errors: *const AsanErrors) -> Self { + Self::Ptr(OwnedPtr::Ptr(errors)) } - /// gets the [`struct@AsanErrors`] from the previous run + /// Gets the [`struct@AsanErrors`] from the previous run #[must_use] - pub fn errors(&self) -> Option<&AsanErrors> { - match &self.errors { - OwnedPtr::Ptr(p) => unsafe { p.as_ref().unwrap().as_ref() }, - OwnedPtr::Owned(b) => b.as_ref().as_ref(), + pub fn errors(&self) -> AsanErrors { + match self { + Self::Ptr(errors) => match errors { + OwnedPtr::Ptr(p) => unsafe { p.as_ref().unwrap().clone() }, + OwnedPtr::Owned(b) => b.as_ref().clone(), + }, + Self::Static => AsanErrors::get_mut_blocking().clone(), } } } @@ -648,16 +664,12 @@ where let observer = observers .match_name::("AsanErrors") .expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); - match observer.errors() { - None => Ok(false), - Some(errors) => { - if errors.errors.is_empty() { - Ok(false) - } else { - self.errors = Some(errors.clone()); - Ok(true) - } - } + let errors = observer.errors(); + if errors.is_empty() { + Ok(false) + } else { + self.errors = Some(errors); + Ok(true) } } diff --git a/libafl_frida/src/asan/hook_funcs.rs b/libafl_frida/src/asan/hook_funcs.rs index 460144da1e..7d9589634f 100644 --- a/libafl_frida/src/asan/hook_funcs.rs +++ b/libafl_frida/src/asan/hook_funcs.rs @@ -344,7 +344,7 @@ impl AsanRuntime { fn write(fd: i32, buf: *const c_void, count: usize) -> usize; } if !(self.shadow_check_func().unwrap())(buf, count) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "write".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), buf as usize, @@ -361,7 +361,7 @@ impl AsanRuntime { fn read(fd: i32, buf: *mut c_void, count: usize) -> usize; } if !(self.shadow_check_func().unwrap())(buf, count) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "read".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), buf as usize, @@ -378,7 +378,7 @@ impl AsanRuntime { fn fgets(s: *mut c_void, size: u32, stream: *mut c_void) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(s, size as usize) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "fgets".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -395,7 +395,7 @@ impl AsanRuntime { fn memcmp(s1: *const c_void, s2: *const c_void, n: usize) -> i32; } if !(self.shadow_check_func().unwrap())(s1, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -404,7 +404,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -421,7 +421,7 @@ impl AsanRuntime { fn memcpy(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(dest, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -430,7 +430,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -448,7 +448,7 @@ impl AsanRuntime { fn mempcpy(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(dest, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "mempcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -457,7 +457,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "mempcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -474,7 +474,7 @@ impl AsanRuntime { fn memmove(dest: *mut c_void, src: *const c_void, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(dest, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memmove".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -483,7 +483,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memmove".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -500,7 +500,7 @@ impl AsanRuntime { fn memset(dest: *mut c_void, c: i32, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(dest, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -517,7 +517,7 @@ impl AsanRuntime { fn memchr(s: *mut c_void, c: i32, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memchr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -535,7 +535,7 @@ impl AsanRuntime { fn memrchr(s: *mut c_void, c: i32, n: usize) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memrchr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -563,7 +563,7 @@ impl AsanRuntime { ) -> *mut c_void; } if !(self.shadow_check_func().unwrap())(haystack, haystacklen) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memmem".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), haystack as usize, @@ -572,7 +572,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(needle, needlelen) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "memmem".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), needle as usize, @@ -590,7 +590,7 @@ impl AsanRuntime { fn bzero(s: *mut c_void, n: usize); } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "bzero".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -608,7 +608,7 @@ impl AsanRuntime { fn explicit_bzero(s: *mut c_void, n: usize); } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "explicit_bzero".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -626,7 +626,7 @@ impl AsanRuntime { fn bcmp(s1: *const c_void, s2: *const c_void, n: usize) -> i32; } if !(self.shadow_check_func().unwrap())(s1, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "bcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -635,7 +635,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "bcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -653,7 +653,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s as *const c_void, unsafe { strlen(s) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strchr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -671,7 +671,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s as *const c_void, unsafe { strlen(s) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strrchr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -689,7 +689,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s1 as *const c_void, unsafe { strlen(s1) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcasecmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -698,7 +698,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2 as *const c_void, unsafe { strlen(s2) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcasecmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -715,7 +715,7 @@ impl AsanRuntime { fn strncasecmp(s1: *const c_char, s2: *const c_char, n: usize) -> i32; } if !(self.shadow_check_func().unwrap())(s1 as *const c_void, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strncasecmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -724,7 +724,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2 as *const c_void, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strncasecmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -742,7 +742,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s1 as *const c_void, unsafe { strlen(s1) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcat".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -751,7 +751,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2 as *const c_void, unsafe { strlen(s2) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcat".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -769,7 +769,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s1 as *const c_void, unsafe { strlen(s1) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -778,7 +778,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2 as *const c_void, unsafe { strlen(s2) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -796,7 +796,7 @@ impl AsanRuntime { fn strnlen(s: *const c_char, n: usize) -> usize; } if !(self.shadow_check_func().unwrap())(s1 as *const c_void, unsafe { strnlen(s1, n) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strncmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -805,7 +805,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(s2 as *const c_void, unsafe { strnlen(s2, n) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strncmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -823,7 +823,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(dest as *const c_void, unsafe { strlen(src) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "strcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -832,7 +832,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src as *const c_void, unsafe { strlen(src) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -849,7 +849,7 @@ impl AsanRuntime { fn strncpy(dest: *mut c_char, src: *const c_char, n: usize) -> *mut c_char; } if !(self.shadow_check_func().unwrap())(dest as *const c_void, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "strncpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -858,7 +858,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src as *const c_void, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strncpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -876,7 +876,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(dest as *const c_void, unsafe { strlen(src) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "stpcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -885,7 +885,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(src as *const c_void, unsafe { strlen(src) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "stpcpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -904,7 +904,7 @@ impl AsanRuntime { } let size = unsafe { strlen(s) }; if !(self.shadow_check_func().unwrap())(s as *const c_void, size) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strdup".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -927,7 +927,7 @@ impl AsanRuntime { } let size = unsafe { strlen(s) }; if !(self.shadow_check_func().unwrap())(s as *const c_void, size) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strlen".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -945,7 +945,7 @@ impl AsanRuntime { } let size = unsafe { strnlen(s, n) }; if !(self.shadow_check_func().unwrap())(s as *const c_void, size) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strnlen".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -965,7 +965,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(haystack as *const c_void, unsafe { strlen(haystack) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strstr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), haystack as usize, @@ -975,7 +975,7 @@ impl AsanRuntime { } if !(self.shadow_check_func().unwrap())(needle as *const c_void, unsafe { strlen(needle) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strstr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), needle as usize, @@ -999,7 +999,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(haystack as *const c_void, unsafe { strlen(haystack) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcasestr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), haystack as usize, @@ -1009,7 +1009,7 @@ impl AsanRuntime { } if !(self.shadow_check_func().unwrap())(needle as *const c_void, unsafe { strlen(needle) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "strcasestr".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), needle as usize, @@ -1027,7 +1027,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s as *const c_void, unsafe { strlen(s) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "atoi".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1046,7 +1046,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s as *const c_void, unsafe { strlen(s) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "atol".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1065,7 +1065,7 @@ impl AsanRuntime { fn strlen(s: *const c_char) -> usize; } if !(self.shadow_check_func().unwrap())(s as *const c_void, unsafe { strlen(s) }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "atoll".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1084,7 +1084,7 @@ impl AsanRuntime { } let size = unsafe { wcslen(s) }; if !(self.shadow_check_func().unwrap())(s as *const c_void, (size + 1) * 2) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "wcslen".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1105,7 +1105,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(dest as *const c_void, unsafe { (wcslen(src) + 1) * 2 }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "wcscpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), dest as usize, @@ -1116,7 +1116,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(src as *const c_void, unsafe { (wcslen(src) + 1) * 2 }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "wcscpy".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), src as usize, @@ -1137,7 +1137,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(s1 as *const c_void, unsafe { (wcslen(s1) + 1) * 2 }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "wcscmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s1 as usize, @@ -1148,7 +1148,7 @@ impl AsanRuntime { if !(self.shadow_check_func().unwrap())(s2 as *const c_void, unsafe { (wcslen(s2) + 1) * 2 }) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgRead(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead(( "wcscmp".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s2 as usize, @@ -1166,7 +1166,7 @@ impl AsanRuntime { fn memset_pattern4(s: *mut c_void, p4: *const c_void, n: usize); } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern4".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1175,7 +1175,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(p4, n / 4) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern4".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), p4 as usize, @@ -1193,7 +1193,7 @@ impl AsanRuntime { fn memset_pattern8(s: *mut c_void, p8: *const c_void, n: usize); } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern8".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1202,7 +1202,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(p8, n / 8) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern8".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), p8 as usize, @@ -1220,7 +1220,7 @@ impl AsanRuntime { fn memset_pattern16(s: *mut c_void, p16: *const c_void, n: usize); } if !(self.shadow_check_func().unwrap())(s, n) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern16".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), s as usize, @@ -1229,7 +1229,7 @@ impl AsanRuntime { ))); } if !(self.shadow_check_func().unwrap())(p16, n / 16) { - AsanErrors::get_mut().report_error(AsanError::BadFuncArgWrite(( + AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgWrite(( "memset_pattern16".to_string(), self.real_address_for_stalked(AsanRuntime::pc()), p16 as usize, diff --git a/libafl_frida/src/executor.rs b/libafl_frida/src/executor.rs index 21109542f0..b3e437675c 100644 --- a/libafl_frida/src/executor.rs +++ b/libafl_frida/src/executor.rs @@ -1,3 +1,5 @@ +#[cfg(all(unix, not(test)))] +use core::borrow::Borrow; use core::fmt::{self, Debug, Formatter}; use std::{ffi::c_void, marker::PhantomData}; @@ -18,9 +20,8 @@ use libafl::{ Error, }; -#[cfg(not(test))] -#[cfg(unix)] -use crate::asan::errors::ASAN_ERRORS; +#[cfg(all(unix, not(test)))] +use crate::asan::errors::AsanErrors; use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple}; #[cfg(windows)] use crate::windows_hooks::initialize; @@ -104,11 +105,10 @@ where self.stalker.deactivate(); } - #[cfg(not(test))] - #[cfg(unix)] + #[cfg(all(unix, not(test)))] unsafe { - if ASAN_ERRORS.is_some() && !ASAN_ERRORS.as_ref().unwrap().is_empty() { - log::error!("Crashing target as it had ASAN errors"); + if !AsanErrors::get_mut_blocking().borrow().is_empty() { + log::error!("Crashing target as it had ASan errors"); libc::raise(libc::SIGABRT); } }