diff --git a/libafl_frida/Cargo.toml b/libafl_frida/Cargo.toml index 71cf32c4f3..fba4e13d02 100644 --- a/libafl_frida/Cargo.toml +++ b/libafl_frida/Cargo.toml @@ -82,6 +82,7 @@ frida-gum = { version = "0.13.6", features = [ "invocation-listener", "module-names", ] } +os-thread-local = "0.1.3" dynasmrt = "2" color-backtrace = { version = "0.6", features = ["resolve-modules"] } diff --git a/libafl_frida/src/asan/asan_rt.rs b/libafl_frida/src/asan/asan_rt.rs index 7d2829b8e5..08d7055037 100644 --- a/libafl_frida/src/asan/asan_rt.rs +++ b/libafl_frida/src/asan/asan_rt.rs @@ -32,6 +32,7 @@ use frida_gum_sys::Insn; use hashbrown::HashMap; use libafl_bolts::{cli::FuzzerOptions, AsSlice}; use libc::wchar_t; +use os_thread_local::ThreadLocal; use rangemap::RangeMap; #[cfg(target_arch = "aarch64")] use yaxpeax_arch::Arch; @@ -94,10 +95,6 @@ pub const ASAN_SAVE_REGISTER_NAMES: [&str; ASAN_SAVE_REGISTER_COUNT] = [ "actual rip", ]; -thread_local! { - static ASAN_IN_HOOK: Cell = const { Cell::new(false) }; -} - /// The count of registers that need to be saved by the asan runtime #[cfg(target_arch = "aarch64")] pub const ASAN_SAVE_REGISTER_COUNT: usize = 32; @@ -140,6 +137,7 @@ pub struct AsanRuntime { pc: Option, hooks: Vec, pub(crate) hooks_enabled: bool, + thread_in_hook: ThreadLocal>, #[cfg(target_arch = "aarch64")] eh_frame: [u32; ASAN_EH_FRAME_DWORD_COUNT], } @@ -512,18 +510,13 @@ impl AsanRuntime { //is this necessary? The stalked return address will always be the real return address // let real_address = this.real_address_for_stalked(invocation.return_addr()); let original = [<$name:snake:upper _PTR>].get().unwrap(); - if this.hooks_enabled { - let previous_hook_state = this.hooks_enabled; - this.hooks_enabled = false; + if !this.thread_in_hook.with(|f| f.get()) && this.hooks_enabled { + this.thread_in_hook.with(|f|f.set(true)); let ret = this.[](*original, $($param),*); - this.hooks_enabled = previous_hook_state; + this.thread_in_hook.with(|f|f.set(false)); ret } else { - - let previous_hook_state = this.hooks_enabled; - this.hooks_enabled = false; let ret = (original)($($param),*); - this.hooks_enabled = previous_hook_state; ret } } @@ -556,10 +549,10 @@ impl AsanRuntime { //is this necessary? The stalked return address will always be the real return address // let real_address = this.real_address_for_stalked(invocation.return_addr()); let original = [<$lib_ident:snake:upper _ $name:snake:upper _PTR>].get().unwrap(); - if !ASAN_IN_HOOK.get() && this.hooks_enabled { - ASAN_IN_HOOK.set(true); + if !this.thread_in_hook.with(|f| f.get()) && this.hooks_enabled { + this.thread_in_hook.with(|f|f.set(true)); let ret = this.[](*original, $($param),*); - ASAN_IN_HOOK.set(false); + this.thread_in_hook.with(|f|f.set(false)); ret } else { let ret = (original)($($param),*); @@ -599,10 +592,10 @@ impl AsanRuntime { let this = &mut *(invocation.replacement_data().unwrap().0 as *mut AsanRuntime); let original = [<$name:snake:upper _PTR>].get().unwrap(); - if !ASAN_IN_HOOK.get() && this.hooks_enabled && this.[]($($param),*){ - ASAN_IN_HOOK.set(true); + if !this.thread_in_hook.with(|f| f.get()) && this.hooks_enabled && this.[]($($param),*){ + this.thread_in_hook.with(|f|f.set(true)); let ret = this.[](*original, $($param),*); - ASAN_IN_HOOK.set(false); + this.thread_in_hook.with(|f|f.set(false)); ret } else { let ret = (original)($($param),*); @@ -638,10 +631,10 @@ impl AsanRuntime { let this = &mut *(invocation.replacement_data().unwrap().0 as *mut AsanRuntime); let original = [<$lib_ident:snake:upper _ $name:snake:upper _PTR>].get().unwrap(); - if !ASAN_IN_HOOK.get() && this.hooks_enabled && this.[]($($param),*){ - ASAN_IN_HOOK.set(true); + if !this.thread_in_hook.with(|f|f.get()) && this.hooks_enabled && this.[]($($param),*){ + this.thread_in_hook.with(|f|f.set(true)); let ret = this.[](*original, $($param),*); - ASAN_IN_HOOK.set(false); + this.thread_in_hook.with(|f|f.set(false)); ret } else { let ret = (original)($($param),*); @@ -2749,6 +2742,7 @@ impl Default for AsanRuntime { pc: None, hooks: Vec::new(), hooks_enabled: false, + thread_in_hook: ThreadLocal::new(|| Cell::new(false)), } } }