Exclude ASAN DSO address ranges in QEMU AsanModule (#3180)
Co-authored-by: Romain Malmain <romain.malmain@pm.me>
This commit is contained in:
parent
1620bd766f
commit
3b23012faf
@ -14,7 +14,7 @@ use std::{
|
|||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use libafl::{executors::ExitKind, observers::ObserversTuple};
|
use libafl::{executors::ExitKind, observers::ObserversTuple};
|
||||||
use libafl_bolts::os::unix_signals::Signal;
|
use libafl_bolts::os::unix_signals::Signal;
|
||||||
use libafl_qemu_sys::GuestAddr;
|
use libafl_qemu_sys::{GuestAddr, MapInfo};
|
||||||
use libc::{
|
use libc::{
|
||||||
MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE, c_void,
|
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,
|
empty: bool,
|
||||||
rt: Pin<Box<AsanGiovese>>,
|
rt: Pin<Box<AsanGiovese>>,
|
||||||
filter: StdAddressFilter,
|
filter: StdAddressFilter,
|
||||||
|
asan_lib: Option<String>,
|
||||||
|
asan_mappings: Option<Vec<MapInfo>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AsanGiovese {
|
pub struct AsanGiovese {
|
||||||
@ -408,6 +410,8 @@ impl AsanModule {
|
|||||||
empty: true,
|
empty: true,
|
||||||
rt,
|
rt,
|
||||||
filter,
|
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
|
// Let the use skip preloading the ASAN DSO. Maybe they want to use
|
||||||
// their own implementation.
|
// 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 current = env::current_exe().unwrap();
|
||||||
let asan_lib = fs::canonicalize(current)
|
let asan_lib = fs::canonicalize(current)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -1034,13 +1038,18 @@ where
|
|||||||
args.insert(1, "LD_PRELOAD=".to_string() + &asan_lib);
|
args.insert(1, "LD_PRELOAD=".to_string() + &asan_lib);
|
||||||
args.insert(1, "-E".into());
|
args.insert(1, "-E".into());
|
||||||
}
|
}
|
||||||
}
|
Some(asan_lib)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
AsanGiovese::init(&mut self.rt, emulator_modules.hooks().qemu_hooks());
|
AsanGiovese::init(&mut self.rt, emulator_modules.hooks().qemu_hooks());
|
||||||
}
|
}
|
||||||
|
|
||||||
*qemu_params = QemuParams::Cli(args);
|
*qemu_params = QemuParams::Cli(args);
|
||||||
|
|
||||||
|
self.asan_lib = asan_lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_qemu_init<ET>(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules<ET, I, S>)
|
fn post_qemu_init<ET>(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules<ET, I, S>)
|
||||||
@ -1056,12 +1065,23 @@ where
|
|||||||
|
|
||||||
fn first_exec<ET>(
|
fn first_exec<ET>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_qemu: Qemu,
|
qemu: Qemu,
|
||||||
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
emulator_modules: &mut EmulatorModules<ET, I, S>,
|
||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
) where
|
) where
|
||||||
ET: EmulatorModuleTuple<I, S>,
|
ET: EmulatorModuleTuple<I, S>,
|
||||||
{
|
{
|
||||||
|
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::<Vec<MapInfo>>();
|
||||||
|
self.asan_mappings = Some(asan_mappings);
|
||||||
|
}
|
||||||
|
|
||||||
emulator_modules.reads(
|
emulator_modules.reads(
|
||||||
Hook::Function(gen_readwrite_asan::<ET, I, S>),
|
Hook::Function(gen_readwrite_asan::<ET, I, S>),
|
||||||
Hook::Function(trace_read_asan::<ET, I, S, 1>),
|
Hook::Function(trace_read_asan::<ET, I, S, 1>),
|
||||||
@ -1173,11 +1193,21 @@ where
|
|||||||
S: Unpin,
|
S: Unpin,
|
||||||
{
|
{
|
||||||
let h = emulator_modules.get_mut::<AsanModule>().unwrap();
|
let h = emulator_modules.get_mut::<AsanModule>().unwrap();
|
||||||
if h.must_instrument(pc) {
|
if !h.must_instrument(pc) {
|
||||||
Some(pc.into())
|
return None;
|
||||||
} else {
|
|
||||||
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<ET, I, S, const N: usize>(
|
pub fn trace_read_asan<ET, I, S, const N: usize>(
|
||||||
@ -1260,11 +1290,21 @@ where
|
|||||||
S: Unpin,
|
S: Unpin,
|
||||||
{
|
{
|
||||||
let h = emulator_modules.get_mut::<AsanModule>().unwrap();
|
let h = emulator_modules.get_mut::<AsanModule>().unwrap();
|
||||||
if h.must_instrument(pc) {
|
if !h.must_instrument(pc) {
|
||||||
Some(pc.into())
|
return Some(0);
|
||||||
} else {
|
|
||||||
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<ET, I, S, const N: usize>(
|
pub fn trace_write_asan_snapshot<ET, I, S, const N: usize>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user