Add filter to ASAN module in qemu_launcher (#3089)
also add filters to rasan runner. Co-authored-by: Your Name <you@example.com>
This commit is contained in:
parent
1b85a92577
commit
30946641cd
@ -10,8 +10,8 @@ use libafl::{
|
||||
};
|
||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list};
|
||||
use libafl_qemu::modules::{
|
||||
asan::AsanModule, asan_guest::AsanGuestModule, cmplog::CmpLogModule, DrCovModule,
|
||||
InjectionModule,
|
||||
asan::AsanModule, asan_guest::AsanGuestModule, cmplog::CmpLogModule,
|
||||
utils::filters::StdAddressFilter, DrCovModule, InjectionModule,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@ -111,6 +111,17 @@ impl Client<'_> {
|
||||
.client_description(client_description)
|
||||
.extra_tokens(extra_tokens);
|
||||
|
||||
let asan_filter = if let Some(include_asan) = &self.options.include_asan {
|
||||
log::info!("ASAN includes: {include_asan:#x?}");
|
||||
StdAddressFilter::allow_list(include_asan.to_vec())
|
||||
} else if let Some(exclude_asan) = &self.options.exclude_asan {
|
||||
log::info!("ASAN excludes: {exclude_asan:#x?}");
|
||||
StdAddressFilter::deny_list(exclude_asan.to_vec())
|
||||
} else {
|
||||
log::info!("ASAN no additional filter");
|
||||
StdAddressFilter::default()
|
||||
};
|
||||
|
||||
if self.options.rerun_input.is_some() {
|
||||
if is_drcov {
|
||||
// Special code path for re-running inputs with DrCov and Asan.
|
||||
@ -123,7 +134,13 @@ impl Client<'_> {
|
||||
.filename(drcov.clone())
|
||||
.full_trace(true)
|
||||
.build(),
|
||||
unsafe { AsanModule::builder().env(&env).asan_report().build() }
|
||||
unsafe {
|
||||
AsanModule::builder()
|
||||
.env(&env)
|
||||
.filter(asan_filter)
|
||||
.asan_report()
|
||||
.build()
|
||||
}
|
||||
);
|
||||
|
||||
instance_builder.build().run(args, modules, state)
|
||||
@ -133,7 +150,7 @@ impl Client<'_> {
|
||||
.filename(drcov.clone())
|
||||
.full_trace(true)
|
||||
.build(),
|
||||
AsanGuestModule::default(&env),
|
||||
AsanGuestModule::new(&env, asan_filter),
|
||||
);
|
||||
|
||||
instance_builder.build().run(args, modules, state)
|
||||
@ -146,12 +163,17 @@ impl Client<'_> {
|
||||
instance_builder.build().run(args, modules, state)
|
||||
}
|
||||
} else if is_asan {
|
||||
let modules =
|
||||
tuple_list!(unsafe { AsanModule::builder().env(&env).asan_report().build() });
|
||||
let modules = tuple_list!(unsafe {
|
||||
AsanModule::builder()
|
||||
.env(&env)
|
||||
.filter(asan_filter)
|
||||
.asan_report()
|
||||
.build()
|
||||
});
|
||||
|
||||
instance_builder.build().run(args, modules, state)
|
||||
} else if is_asan_guest {
|
||||
let modules = tuple_list!(AsanGuestModule::default(&env));
|
||||
let modules = tuple_list!(AsanGuestModule::new(&env, asan_filter));
|
||||
|
||||
instance_builder.build().run(args, modules, state)
|
||||
} else {
|
||||
@ -165,7 +187,7 @@ impl Client<'_> {
|
||||
args,
|
||||
tuple_list!(
|
||||
CmpLogModule::default(),
|
||||
AsanModule::builder().env(&env).build(),
|
||||
AsanModule::builder().env(&env).filter(asan_filter).build(),
|
||||
injection_module,
|
||||
),
|
||||
state,
|
||||
@ -175,7 +197,7 @@ impl Client<'_> {
|
||||
args,
|
||||
tuple_list!(
|
||||
CmpLogModule::default(),
|
||||
AsanModule::builder().env(&env).build()
|
||||
AsanModule::builder().env(&env).filter(asan_filter).build()
|
||||
),
|
||||
state,
|
||||
)
|
||||
@ -186,7 +208,7 @@ impl Client<'_> {
|
||||
args,
|
||||
tuple_list!(
|
||||
CmpLogModule::default(),
|
||||
AsanGuestModule::default(&env),
|
||||
AsanGuestModule::new(&env, asan_filter),
|
||||
injection_module
|
||||
),
|
||||
state,
|
||||
@ -194,7 +216,10 @@ impl Client<'_> {
|
||||
} else {
|
||||
instance_builder.build().run(
|
||||
args,
|
||||
tuple_list!(CmpLogModule::default(), AsanGuestModule::default(&env),),
|
||||
tuple_list!(
|
||||
CmpLogModule::default(),
|
||||
AsanGuestModule::new(&env, asan_filter),
|
||||
),
|
||||
state,
|
||||
)
|
||||
}
|
||||
@ -202,20 +227,25 @@ impl Client<'_> {
|
||||
if let Some(injection_module) = injection_module {
|
||||
instance_builder.build().run(
|
||||
args,
|
||||
tuple_list!(AsanModule::builder().env(&env).build(), injection_module),
|
||||
tuple_list!(
|
||||
AsanModule::builder().env(&env).filter(asan_filter).build(),
|
||||
injection_module
|
||||
),
|
||||
state,
|
||||
)
|
||||
} else {
|
||||
instance_builder.build().run(
|
||||
args,
|
||||
tuple_list!(AsanModule::builder().env(&env).build()),
|
||||
tuple_list!(AsanModule::builder().env(&env).filter(asan_filter).build()),
|
||||
state,
|
||||
)
|
||||
}
|
||||
} else if is_asan_guest {
|
||||
instance_builder
|
||||
.build()
|
||||
.run(args, tuple_list!(AsanGuestModule::default(&env)), state)
|
||||
instance_builder.build().run(
|
||||
args,
|
||||
tuple_list!(AsanGuestModule::new(&env, asan_filter)),
|
||||
state,
|
||||
)
|
||||
} else if is_cmplog {
|
||||
if let Some(injection_module) = injection_module {
|
||||
instance_builder.build().run(
|
||||
|
@ -68,12 +68,18 @@ pub struct FuzzerOptions {
|
||||
#[arg(long = "iterations", help = "Maximum number of iterations")]
|
||||
pub iterations: Option<u64>,
|
||||
|
||||
#[arg(long = "include", help="Include address ranges", value_parser = FuzzerOptions::parse_ranges)]
|
||||
#[arg(long = "include", help="Include coverage address ranges", value_parser = FuzzerOptions::parse_ranges)]
|
||||
pub include: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(long = "exclude", help="Exclude address ranges", value_parser = FuzzerOptions::parse_ranges, conflicts_with="include")]
|
||||
#[arg(long = "exclude", help="Exclude coverage address ranges", value_parser = FuzzerOptions::parse_ranges, conflicts_with="include")]
|
||||
pub exclude: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(long = "include-asan", help="Include asan address ranges", value_parser = FuzzerOptions::parse_ranges)]
|
||||
pub include_asan: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(long = "exclude-asan", help="Exclude asan address ranges", value_parser = FuzzerOptions::parse_ranges, conflicts_with="include_asan")]
|
||||
pub exclude_asan: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(
|
||||
short = 'd',
|
||||
help = "Write a DrCov Trace for the current input. Requires -r."
|
||||
|
@ -14,7 +14,7 @@ test: test_asan
|
||||
|
||||
pretty_rust:
|
||||
#!/bin/sh
|
||||
MAIN_LLVM_VERSION=$LLVM_VERSION cargo run --manifest-path ../../utils/libafl_fmt/Cargo.toml --release -- -v
|
||||
MAIN_LLVM_VERSION=$LLVM_VERSION cargo run --manifest-path ../../utils/libafl_repo_tools/Cargo.toml --release -- -v
|
||||
|
||||
pretty_toml:
|
||||
#!/bin/sh
|
||||
|
@ -1,12 +1,12 @@
|
||||
use std::{env, fmt::Write};
|
||||
use std::{env, fmt::Write, ops::Range};
|
||||
|
||||
use clap::{Parser, builder::Str};
|
||||
use libafl_bolts::{Error, tuples::tuple_list};
|
||||
use libafl_qemu::{
|
||||
Emulator, NopEmulatorDriver, NopSnapshotManager, QemuExitError, QemuInitError,
|
||||
Emulator, GuestAddr, NopEmulatorDriver, NopSnapshotManager, QemuExitError, QemuInitError,
|
||||
command::NopCommandManager,
|
||||
elf::EasyElf,
|
||||
modules::{AsanGuestModule, AsanModule, EmulatorModuleTuple},
|
||||
modules::{AsanGuestModule, AsanModule, EmulatorModuleTuple, utils::filters::StdAddressFilter},
|
||||
};
|
||||
use log::{error, info};
|
||||
use thiserror::Error;
|
||||
@ -60,10 +60,37 @@ pub struct FuzzerOptions {
|
||||
#[clap(short, long, help = "Enable output from the fuzzer clients")]
|
||||
pub verbose: bool,
|
||||
|
||||
#[arg(long = "include-asan", help="Include asan address ranges", value_parser = FuzzerOptions::parse_ranges)]
|
||||
pub include_asan: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(long = "exclude-asan", help="Exclude asan address ranges", value_parser = FuzzerOptions::parse_ranges, conflicts_with="include_asan")]
|
||||
pub exclude_asan: Option<Vec<Range<GuestAddr>>>,
|
||||
|
||||
#[arg(last = true, help = "Arguments passed to the target")]
|
||||
pub args: Vec<String>,
|
||||
}
|
||||
|
||||
impl FuzzerOptions {
|
||||
fn parse_ranges(src: &str) -> Result<Range<GuestAddr>, Error> {
|
||||
let parts = src.split('-').collect::<Vec<&str>>();
|
||||
if parts.len() == 2 {
|
||||
let start =
|
||||
GuestAddr::from_str_radix(parts[0].trim_start_matches("0x"), 16).map_err(|e| {
|
||||
Error::illegal_argument(format!("Invalid start address: {} ({e:})", parts[0]))
|
||||
})?;
|
||||
let end =
|
||||
GuestAddr::from_str_radix(parts[1].trim_start_matches("0x"), 16).map_err(|e| {
|
||||
Error::illegal_argument(format!("Invalid end address: {} ({e:})", parts[1]))
|
||||
})?;
|
||||
Ok(Range { start, end })
|
||||
} else {
|
||||
Err(Error::illegal_argument(format!(
|
||||
"Invalid range provided: {src:}"
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fuzz() {
|
||||
env_logger::init();
|
||||
let mut options = FuzzerOptions::parse();
|
||||
@ -78,14 +105,25 @@ pub fn fuzz() {
|
||||
.filter(|(k, _v)| k != "LD_LIBRARY_PATH")
|
||||
.collect::<Vec<(String, String)>>();
|
||||
|
||||
let asan_filter = if let Some(include_asan) = &options.include_asan {
|
||||
info!("ASAN includes: {include_asan:#x?}");
|
||||
StdAddressFilter::allow_list(include_asan.to_vec())
|
||||
} else if let Some(exclude_asan) = &options.exclude_asan {
|
||||
info!("ASAN excludes: {exclude_asan:#x?}");
|
||||
StdAddressFilter::deny_list(exclude_asan.to_vec())
|
||||
} else {
|
||||
info!("ASAN no additional filter");
|
||||
StdAddressFilter::default()
|
||||
};
|
||||
|
||||
let ret = if options.asan {
|
||||
info!("Enabling ASAN");
|
||||
let modules = tuple_list!(AsanModule::builder().env(&env).build());
|
||||
let modules = tuple_list!(AsanModule::builder().env(&env).filter(asan_filter).build());
|
||||
info!("Modules: {:#?}", modules);
|
||||
run(options, modules)
|
||||
} else if options.gasan {
|
||||
info!("Enabling Guest ASAN");
|
||||
let modules = tuple_list!(AsanGuestModule::default(&env));
|
||||
let modules = tuple_list!(AsanGuestModule::new(&env, asan_filter));
|
||||
info!("Modules: {:#?}", modules);
|
||||
run(options, modules)
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user