diff --git a/libafl_qemu/src/modules/usermode/asan.rs b/libafl_qemu/src/modules/usermode/asan.rs index 76c6795049..cef2513dd9 100644 --- a/libafl_qemu/src/modules/usermode/asan.rs +++ b/libafl_qemu/src/modules/usermode/asan.rs @@ -14,7 +14,7 @@ use std::{ use hashbrown::{HashMap, HashSet}; use libafl::{executors::ExitKind, observers::ObserversTuple}; use libafl_bolts::os::unix_signals::Signal; -use libafl_qemu_sys::GuestAddr; +use libafl_qemu_sys::{GuestAddr, MapInfo}; use libc::{ MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE, c_void, }; @@ -61,6 +61,8 @@ pub struct AsanModule { empty: bool, rt: Pin>, filter: StdAddressFilter, + asan_lib: Option, + asan_mappings: Option>, } pub struct AsanGiovese { @@ -408,6 +410,8 @@ impl AsanModule { empty: true, rt, filter, + asan_lib: None, + asan_mappings: None, } } @@ -981,7 +985,7 @@ where // Let the use skip preloading the ASAN DSO. Maybe they want to use // their own implementation. - if env::var_os("SKIP_ASAN_LD_PRELOAD").is_none() { + let asan_lib = if env::var_os("SKIP_ASAN_LD_PRELOAD").is_none() { let current = env::current_exe().unwrap(); let asan_lib = fs::canonicalize(current) .unwrap() @@ -1034,13 +1038,18 @@ where args.insert(1, "LD_PRELOAD=".to_string() + &asan_lib); args.insert(1, "-E".into()); } - } + Some(asan_lib) + } else { + None + }; unsafe { AsanGiovese::init(&mut self.rt, emulator_modules.hooks().qemu_hooks()); } *qemu_params = QemuParams::Cli(args); + + self.asan_lib = asan_lib; } fn post_qemu_init(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules) @@ -1056,12 +1065,23 @@ where fn first_exec( &mut self, - _qemu: Qemu, + qemu: Qemu, emulator_modules: &mut EmulatorModules, _state: &mut S, ) where ET: EmulatorModuleTuple, { + if let Some(asan_lib) = &self.asan_lib { + let asan_mappings = qemu + .mappings() + .filter(|m| match m.path() { + Some(p) => p == asan_lib, + None => false, + }) + .collect::>(); + self.asan_mappings = Some(asan_mappings); + } + emulator_modules.reads( Hook::Function(gen_readwrite_asan::), Hook::Function(trace_read_asan::), @@ -1173,11 +1193,21 @@ where S: Unpin, { let h = emulator_modules.get_mut::().unwrap(); - if h.must_instrument(pc) { - Some(pc.into()) - } else { - None + if !h.must_instrument(pc) { + return None; + } + + // Don't sanitize the sanitizer! + if let Some(asan_mappings) = &h.asan_mappings { + if asan_mappings + .iter() + .any(|m| m.start() <= pc && pc < m.end()) + { + return None; + } } + + Some(pc.into()) } pub fn trace_read_asan( @@ -1260,11 +1290,21 @@ where S: Unpin, { let h = emulator_modules.get_mut::().unwrap(); - if h.must_instrument(pc) { - Some(pc.into()) - } else { - Some(0) + if !h.must_instrument(pc) { + return Some(0); } + + // Don't sanitize the sanitizer! + if let Some(asan_mappings) = &h.asan_mappings { + if asan_mappings + .iter() + .any(|m| m.start() <= pc && pc < m.end()) + { + return Some(0); + } + } + + Some(pc.into()) } pub fn trace_write_asan_snapshot(