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
This commit is contained in:
Dominik Maier 2024-04-03 11:47:09 +02:00 committed by GitHub
parent 2137ad0f8f
commit d90d232e7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 157 additions and 151 deletions

View File

@ -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,

View File

@ -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())));
}
}

View File

@ -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<AsanErrors> {
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")]

View File

@ -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<AsanErrors> = None;
pub static ASAN_ERRORS: Mutex<AsanErrors> = 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<Option<AsanErrors>>,
pub enum AsanErrorsObserver {
/// Observer referencing a list behind a [`OwnedPtr`] pointer.
Ptr(OwnedPtr<AsanErrors>),
/// Observer referencing the static [`ASAN_ERRORS`] variable.
Static,
}
impl<S> Observer<S> 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<Option<AsanErrors>>) -> Self {
Self { errors }
pub fn new(errors: OwnedPtr<AsanErrors>) -> 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<AsanErrors>) -> 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<AsanErrors>) -> 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,18 +664,14 @@ where
let observer = observers
.match_name::<AsanErrorsObserver>("AsanErrors")
.expect("An AsanErrorsFeedback needs an AsanErrorsObserver");
match observer.errors() {
None => Ok(false),
Some(errors) => {
if errors.errors.is_empty() {
let errors = observer.errors();
if errors.is_empty() {
Ok(false)
} else {
self.errors = Some(errors.clone());
self.errors = Some(errors);
Ok(true)
}
}
}
}
fn append_metadata<EM, OT>(
&mut self,

View File

@ -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,

View File

@ -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);
}
}