From 6ee26a8afaa69b6d645b1d86e9899f7934455536 Mon Sep 17 00:00:00 2001 From: "Dongjia \"toka\" Zhang" Date: Mon, 20 Jan 2025 17:44:44 +0100 Subject: [PATCH] Decouple address_filters() from EmulatorModuleTuple into HasAddressFilters (#2869) * 1 * fixe --- .../binary_only/qemu_launcher/src/instance.rs | 10 ++-- .../qemu_linux_kernel/src/fuzzer.rs | 6 +- .../qemu_linux_process/src/fuzzer.rs | 6 +- libafl_qemu/src/command/mod.rs | 12 ++-- libafl_qemu/src/command/nyx.rs | 12 ++-- libafl_qemu/src/command/parser/mod.rs | 8 +-- libafl_qemu/src/command/parser/nyx.rs | 8 +-- libafl_qemu/src/modules/calls.rs | 13 +++-- libafl_qemu/src/modules/cmplog.rs | 34 ++++++----- libafl_qemu/src/modules/drcov.rs | 14 +++-- libafl_qemu/src/modules/edges/mod.rs | 17 ++++-- libafl_qemu/src/modules/mod.rs | 45 -------------- libafl_qemu/src/modules/usermode/asan.rs | 8 ++- .../src/modules/usermode/asan_guest.rs | 12 +++- .../src/modules/usermode/injections.rs | 8 ++- libafl_qemu/src/modules/usermode/snapshot.rs | 7 ++- libafl_qemu/src/modules/utils/filters.rs | 58 +++++++++++++++++++ 17 files changed, 165 insertions(+), 113 deletions(-) diff --git a/fuzzers/binary_only/qemu_launcher/src/instance.rs b/fuzzers/binary_only/qemu_launcher/src/instance.rs index 5a6a8584bf..75bc28252e 100644 --- a/fuzzers/binary_only/qemu_launcher/src/instance.rs +++ b/fuzzers/binary_only/qemu_launcher/src/instance.rs @@ -27,7 +27,7 @@ use libafl::{ ShadowTracingStage, StagesTuple, StdMutationalStage, }, state::{HasCorpus, StdState}, - Error, HasMetadata, NopFuzzer, + Error, HasMetadata, }; #[cfg(not(feature = "simplemgr"))] use libafl_bolts::shmem::{StdShMem, StdShMemProvider}; @@ -41,8 +41,8 @@ use libafl_qemu::{ modules::{ cmplog::CmpLogObserver, edges::EdgeCoverageFullVariant, - utils::filters::{NopPageFilter, StdAddressFilter}, - EdgeCoverageModule, EmulatorModule, EmulatorModuleTuple, StdEdgeCoverageModule, + utils::filters::{HasAddressFilter, NopPageFilter, StdAddressFilter}, + EdgeCoverageModule, EmulatorModuleTuple, StdEdgeCoverageModule, }, Emulator, GuestAddr, Qemu, QemuExecutor, }; @@ -140,10 +140,10 @@ impl Instance<'_, M> { let qemu = emulator.qemu(); // update address filter after qemu has been initialized - as EmulatorModule>::update_address_filter(emulator.modules_mut() + emulator.modules_mut() .modules_mut() .match_first_type_mut::>() - .expect("Could not find back the edge module"), qemu, self.coverage_filter(qemu)?); + .expect("Could not find back the edge module").update_address_filter(qemu, self.coverage_filter(qemu)?); // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); diff --git a/fuzzers/full_system/qemu_linux_kernel/src/fuzzer.rs b/fuzzers/full_system/qemu_linux_kernel/src/fuzzer.rs index 44d43372f2..909f9e2a6d 100644 --- a/fuzzers/full_system/qemu_linux_kernel/src/fuzzer.rs +++ b/fuzzers/full_system/qemu_linux_kernel/src/fuzzer.rs @@ -40,8 +40,8 @@ use libafl_qemu::{ emu::Emulator, executor::QemuExecutor, modules::{ - cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule, CmpLogModule, - EmulatorModuleTuple, + cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule, + utils::filters::HasAddressFilterTuples, CmpLogModule, EmulatorModuleTuple, }, FastSnapshotManager, NopSnapshotManager, QemuInitError, }; @@ -78,7 +78,7 @@ fn get_emulator( QemuInitError, > where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: HasExecutions + Unpin, { diff --git a/fuzzers/full_system/qemu_linux_process/src/fuzzer.rs b/fuzzers/full_system/qemu_linux_process/src/fuzzer.rs index d88ebe3877..1253fea6e6 100644 --- a/fuzzers/full_system/qemu_linux_process/src/fuzzer.rs +++ b/fuzzers/full_system/qemu_linux_process/src/fuzzer.rs @@ -40,8 +40,8 @@ use libafl_qemu::{ emu::Emulator, executor::QemuExecutor, modules::{ - cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule, CmpLogModule, - EmulatorModuleTuple, + cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule, + utils::filters::HasAddressFilterTuples, CmpLogModule, EmulatorModuleTuple, }, FastSnapshotManager, NopSnapshotManager, QemuInitError, QemuSnapshotManager, }; @@ -78,7 +78,7 @@ fn get_emulator( QemuInitError, > where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: HasExecutions + Unpin, { diff --git a/libafl_qemu/src/command/mod.rs b/libafl_qemu/src/command/mod.rs index 50ccc3a15a..7bb48268d4 100644 --- a/libafl_qemu/src/command/mod.rs +++ b/libafl_qemu/src/command/mod.rs @@ -23,7 +23,7 @@ use crate::{ VersionCommandParser, }, get_exit_arch_regs, - modules::EmulatorModuleTuple, + modules::{utils::filters::HasAddressFilterTuples, EmulatorModuleTuple}, sync_exit::ExitArgs, Emulator, EmulatorDriverError, EmulatorDriverResult, GuestReg, InputLocation, IsSnapshotManager, Qemu, QemuMemoryChunk, QemuRWError, Regs, StdEmulatorDriver, CPU, @@ -98,7 +98,7 @@ macro_rules! define_std_command_manager { impl CommandManager for $name where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -127,7 +127,7 @@ macro_rules! define_std_command_manager { impl IsCommand, StdEmulatorDriver, ET, I, S, SM> for [<$name Commands>] where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -385,7 +385,7 @@ pub struct StartCommand { impl IsCommand, StdEmulatorDriver, ET, I, S, SM> for StartCommand where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -546,7 +546,7 @@ pub struct PageAllowCommand { #[cfg(feature = "systemmode")] impl IsCommand for PageAllowCommand where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: Unpin, S: Unpin, { @@ -574,7 +574,7 @@ pub struct AddressAllowCommand { } impl IsCommand for AddressAllowCommand where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: Unpin, S: Unpin, { diff --git a/libafl_qemu/src/command/nyx.rs b/libafl_qemu/src/command/nyx.rs index 575fb655ea..8a0601105e 100644 --- a/libafl_qemu/src/command/nyx.rs +++ b/libafl_qemu/src/command/nyx.rs @@ -32,7 +32,7 @@ use crate::{ CommandError, CommandManager, IsCommand, NativeCommandParser, }, get_exit_arch_regs, - modules::EmulatorModuleTuple, + modules::{utils::filters::HasAddressFilterTuples, EmulatorModuleTuple}, sync_exit::ExitArgs, Emulator, EmulatorDriverError, EmulatorDriverResult, GuestReg, InputLocation, IsSnapshotManager, NyxEmulatorDriver, Qemu, QemuMemoryChunk, Regs, @@ -98,7 +98,7 @@ macro_rules! define_nyx_command_manager { impl CommandManager for $name where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -133,7 +133,7 @@ macro_rules! define_nyx_command_manager { impl IsCommand, NyxEmulatorDriver, ET, I, S, SM> for [<$name Commands>] where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -295,7 +295,7 @@ pub struct NextPayloadCommand; impl IsCommand, NyxEmulatorDriver, ET, I, S, SM> for NextPayloadCommand where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -359,7 +359,7 @@ pub struct SubmitCR3Command; impl IsCommand, NyxEmulatorDriver, ET, I, S, SM> for SubmitCR3Command where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -407,7 +407,7 @@ impl RangeSubmitCommand { impl IsCommand, NyxEmulatorDriver, ET, I, S, SM> for RangeSubmitCommand where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, diff --git a/libafl_qemu/src/command/parser/mod.rs b/libafl_qemu/src/command/parser/mod.rs index 58c2944fa6..eb51c0cc9b 100644 --- a/libafl_qemu/src/command/parser/mod.rs +++ b/libafl_qemu/src/command/parser/mod.rs @@ -11,7 +11,7 @@ use crate::{ IsCommand, LoadCommand, LqprintfCommand, NativeExitKind, SaveCommand, StartCommand, StdCommandManager, TestCommand, VersionCommand, }, - modules::EmulatorModuleTuple, + modules::{utils::filters::HasAddressFilterTuples, EmulatorModuleTuple}, sync_exit::ExitArgs, GuestReg, IsSnapshotManager, Qemu, QemuMemoryChunk, Regs, StdEmulatorDriver, }; @@ -92,7 +92,7 @@ pub struct StartPhysCommandParser; impl NativeCommandParser, StdEmulatorDriver, ET, I, S, SM> for StartPhysCommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -121,7 +121,7 @@ pub struct StartVirtCommandParser; impl NativeCommandParser, StdEmulatorDriver, ET, I, S, SM> for StartVirtCommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -242,7 +242,7 @@ pub struct VaddrFilterAllowRangeCommandParser; impl NativeCommandParser for VaddrFilterAllowRangeCommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: Unpin, S: Unpin, { diff --git a/libafl_qemu/src/command/parser/nyx.rs b/libafl_qemu/src/command/parser/nyx.rs index 99c303626b..b1bb773d73 100644 --- a/libafl_qemu/src/command/parser/nyx.rs +++ b/libafl_qemu/src/command/parser/nyx.rs @@ -15,7 +15,7 @@ use crate::{ parser::NativeCommandParser, CommandError, NativeExitKind, }, - modules::EmulatorModuleTuple, + modules::{utils::filters::HasAddressFilterTuples, EmulatorModuleTuple}, sync_exit::ExitArgs, IsSnapshotManager, NyxEmulatorDriver, Qemu, QemuMemoryChunk, Regs, }; @@ -80,7 +80,7 @@ pub struct SubmitCR3CommandParser; impl NativeCommandParser, NyxEmulatorDriver, ET, I, S, SM> for SubmitCR3CommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -100,7 +100,7 @@ pub struct RangeSubmitCommandParser; impl NativeCommandParser, NyxEmulatorDriver, ET, I, S, SM> for RangeSubmitCommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, @@ -188,7 +188,7 @@ pub struct NextPayloadCommandParser; impl NativeCommandParser, NyxEmulatorDriver, ET, I, S, SM> for NextPayloadCommandParser where - ET: EmulatorModuleTuple, + ET: EmulatorModuleTuple + HasAddressFilterTuples, I: HasTargetBytes + Unpin, S: Unpin, SM: IsSnapshotManager, diff --git a/libafl_qemu/src/modules/calls.rs b/libafl_qemu/src/modules/calls.rs index 1e97da3509..ab1814612c 100644 --- a/libafl_qemu/src/modules/calls.rs +++ b/libafl_qemu/src/modules/calls.rs @@ -10,6 +10,7 @@ use libafl_bolts::tuples::{Handle, Handled, MatchFirstType, MatchNameRef}; use libafl_qemu_sys::GuestAddr; use thread_local::ThreadLocal; +use super::utils::filters::HasAddressFilter; #[cfg(feature = "systemmode")] use crate::modules::utils::filters::{NopPageFilter, NOP_PAGE_FILTER}; use crate::{ @@ -415,10 +416,6 @@ where S: Unpin, T: CallTraceCollectorTuple + Debug, { - type ModuleAddressFilter = StdAddressFilter; - #[cfg(feature = "systemmode")] - type ModulePageFilter = NopPageFilter; - fn post_qemu_init(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -459,7 +456,15 @@ where .unwrap() .post_exec_all(qemu, input, observers, exit_kind); } +} +impl HasAddressFilter for CallTracerModule +where + T: CallTraceCollectorTuple, +{ + type ModuleAddressFilter = StdAddressFilter; + #[cfg(feature = "systemmode")] + type ModulePageFilter = NopPageFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.filter } diff --git a/libafl_qemu/src/modules/cmplog.rs b/libafl_qemu/src/modules/cmplog.rs index 510da15b00..a69704a148 100644 --- a/libafl_qemu/src/modules/cmplog.rs +++ b/libafl_qemu/src/modules/cmplog.rs @@ -19,7 +19,8 @@ use crate::{capstone, qemu::ArchExtras, CallingConvention}; use crate::{ emu::EmulatorModules, modules::{ - utils::filters::StdAddressFilter, AddressFilter, EmulatorModule, EmulatorModuleTuple, + utils::filters::{HasAddressFilter, StdAddressFilter}, + AddressFilter, EmulatorModule, EmulatorModuleTuple, }, qemu::Hook, Qemu, @@ -75,10 +76,6 @@ where I: Unpin, S: Unpin + HasMetadata, { - type ModuleAddressFilter = StdAddressFilter; - #[cfg(feature = "systemmode")] - type ModulePageFilter = NopPageFilter; - fn first_exec( &mut self, _qemu: Qemu, @@ -95,6 +92,12 @@ where Hook::Raw(trace_cmp8_cmplog), ); } +} + +impl HasAddressFilter for CmpLogModule { + type ModuleAddressFilter = StdAddressFilter; + #[cfg(feature = "systemmode")] + type ModulePageFilter = NopPageFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.address_filter @@ -143,10 +146,6 @@ where I: Unpin, S: Unpin + HasMetadata, { - type ModuleAddressFilter = StdAddressFilter; - #[cfg(feature = "systemmode")] - type ModulePageFilter = NopPageFilter; - const HOOKS_DO_SIDE_EFFECTS: bool = false; fn first_exec( @@ -165,6 +164,12 @@ where Hook::Raw(trace_cmp8_cmplog), ); } +} + +impl HasAddressFilter for CmpLogChildModule { + type ModuleAddressFilter = StdAddressFilter; + #[cfg(feature = "systemmode")] + type ModulePageFilter = NopPageFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.address_filter @@ -408,10 +413,6 @@ where I: Unpin, S: Unpin, { - type ModuleAddressFilter = StdAddressFilter; - #[cfg(feature = "systemmode")] - type ModulePageFilter = NopPageFilter; - fn first_exec( &mut self, _qemu: Qemu, @@ -426,6 +427,13 @@ where Hook::Empty, ); } +} + +#[cfg(feature = "usermode")] +impl HasAddressFilter for CmpLogRoutinesModule { + type ModuleAddressFilter = StdAddressFilter; + #[cfg(feature = "systemmode")] + type ModulePageFilter = NopPageFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.address_filter diff --git a/libafl_qemu/src/modules/drcov.rs b/libafl_qemu/src/modules/drcov.rs index a87f8bb0a6..c565634399 100644 --- a/libafl_qemu/src/modules/drcov.rs +++ b/libafl_qemu/src/modules/drcov.rs @@ -7,6 +7,7 @@ use libafl_targets::drcov::{DrCovBasicBlock, DrCovWriter}; use rangemap::RangeMap; use serde::{Deserialize, Serialize}; +use super::utils::filters::HasAddressFilter; #[cfg(feature = "systemmode")] use crate::modules::utils::filters::{NopPageFilter, NOP_PAGE_FILTER}; use crate::{ @@ -264,10 +265,6 @@ where I: Unpin, S: Unpin + HasMetadata, { - type ModuleAddressFilter = F; - #[cfg(feature = "systemmode")] - type ModulePageFilter = NopPageFilter; - fn post_qemu_init(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -349,6 +346,15 @@ where unsafe fn on_timeout(&mut self) { self.write(); } +} + +impl HasAddressFilter for DrCovModule +where + F: AddressFilter, +{ + type ModuleAddressFilter = F; + #[cfg(feature = "systemmode")] + type ModulePageFilter = NopPageFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.filter diff --git a/libafl_qemu/src/modules/edges/mod.rs b/libafl_qemu/src/modules/edges/mod.rs index 650bd31192..462c06adf5 100644 --- a/libafl_qemu/src/modules/edges/mod.rs +++ b/libafl_qemu/src/modules/edges/mod.rs @@ -34,6 +34,8 @@ pub use child::{ }; use libafl::observers::ConstLenMapObserver; +use super::utils::filters::HasAddressFilter; + /// Standard edge coverage module, adapted to most use cases pub type StdEdgeCoverageModule = StdEdgeCoverageFullModule; @@ -327,10 +329,6 @@ where S: Unpin + HasMetadata, V: EdgeCoverageVariant + 'static, { - type ModuleAddressFilter = AF; - - #[cfg(feature = "systemmode")] - type ModulePageFilter = PF; const HOOKS_DO_SIDE_EFFECTS: bool = V::DO_SIDE_EFFECTS; fn first_exec( @@ -353,7 +351,18 @@ where self.variant.fn_no_hitcount(emulator_modules); } } +} +impl HasAddressFilter + for EdgeCoverageModule +where + AF: AddressFilter, + PF: PageFilter, +{ + type ModuleAddressFilter = AF; + + #[cfg(feature = "systemmode")] + type ModulePageFilter = PF; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.address_filter } diff --git a/libafl_qemu/src/modules/mod.rs b/libafl_qemu/src/modules/mod.rs index 5732231354..054c962a6a 100644 --- a/libafl_qemu/src/modules/mod.rs +++ b/libafl_qemu/src/modules/mod.rs @@ -85,11 +85,6 @@ pub mod utils; /// return values, please refer to the [`EmulatorModules`]. // TODO remove 'static when specialization will be stable pub trait EmulatorModule: 'static + Debug { - type ModuleAddressFilter: AddressFilter; - - #[cfg(feature = "systemmode")] - type ModulePageFilter: PageFilter; - const HOOKS_DO_SIDE_EFFECTS: bool = true; /// Hook run **before** QEMU is initialized. @@ -167,25 +162,6 @@ pub trait EmulatorModule: 'static + Debug { /// /// This is getting executed in a signal handler. unsafe fn on_timeout(&mut self) {} - - fn address_filter(&self) -> &Self::ModuleAddressFilter; - fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter; - fn update_address_filter(&mut self, qemu: Qemu, filter: Self::ModuleAddressFilter) { - *self.address_filter_mut() = filter; - // Necessary because some hooks filter during TB generation. - qemu.flush_jit(); - } - - #[cfg(feature = "systemmode")] - fn page_filter(&self) -> &Self::ModulePageFilter; - #[cfg(feature = "systemmode")] - fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter; - #[cfg(feature = "systemmode")] - fn update_page_filter(&mut self, qemu: Qemu, filter: Self::ModulePageFilter) { - *self.page_filter_mut() = filter; - // Necessary because some hooks filter during TB generation. - qemu.flush_jit(); - } } pub trait EmulatorModuleTuple: @@ -245,11 +221,6 @@ pub trait EmulatorModuleTuple: /// /// This is getting executed in a signal handler. unsafe fn on_timeout_all(&mut self); - - fn allow_address_range_all(&mut self, address_range: Range); - - #[cfg(feature = "systemmode")] - fn allow_page_id_all(&mut self, page_id: GuestPhysAddr); } impl EmulatorModuleTuple for () @@ -314,11 +285,6 @@ where unsafe fn on_crash_all(&mut self) {} unsafe fn on_timeout_all(&mut self) {} - - fn allow_address_range_all(&mut self, _address_range: Range) {} - - #[cfg(feature = "systemmode")] - fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {} } impl EmulatorModuleTuple for (Head, Tail) @@ -403,15 +369,4 @@ where self.0.on_timeout(); self.1.on_timeout_all(); } - - fn allow_address_range_all(&mut self, address_range: Range) { - self.0.address_filter_mut().register(address_range.clone()); - self.1.allow_address_range_all(address_range); - } - - #[cfg(feature = "systemmode")] - fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) { - self.0.page_filter_mut().register(page_id); - self.1.allow_page_id_all(page_id); - } } diff --git a/libafl_qemu/src/modules/usermode/asan.rs b/libafl_qemu/src/modules/usermode/asan.rs index c5d8183f48..6cb45f094c 100644 --- a/libafl_qemu/src/modules/usermode/asan.rs +++ b/libafl_qemu/src/modules/usermode/asan.rs @@ -13,8 +13,8 @@ use rangemap::RangeMap; use crate::{ modules::{ - calls::FullBacktraceCollector, snapshot::SnapshotModule, EmulatorModule, - EmulatorModuleTuple, + calls::FullBacktraceCollector, snapshot::SnapshotModule, utils::filters::HasAddressFilter, + EmulatorModule, EmulatorModuleTuple, }, qemu::MemAccessInfo, sys::TCGTemp, @@ -815,7 +815,6 @@ where I: Unpin, S: Unpin, { - type ModuleAddressFilter = StdAddressFilter; const HOOKS_DO_SIDE_EFFECTS: bool = false; fn pre_qemu_init( @@ -956,7 +955,10 @@ where *exit_kind = ExitKind::Crash; } } +} +impl HasAddressFilter for AsanModule { + type ModuleAddressFilter = StdAddressFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.filter } diff --git a/libafl_qemu/src/modules/usermode/asan_guest.rs b/libafl_qemu/src/modules/usermode/asan_guest.rs index c94bb8bb20..f2df21a3a8 100644 --- a/libafl_qemu/src/modules/usermode/asan_guest.rs +++ b/libafl_qemu/src/modules/usermode/asan_guest.rs @@ -14,7 +14,8 @@ use crate::sys::libafl_tcg_gen_asan; use crate::{ emu::EmulatorModules, modules::{ - utils::filters::StdAddressFilter, AddressFilter, EmulatorModule, EmulatorModuleTuple, + utils::filters::{HasAddressFilter, StdAddressFilter}, + AddressFilter, EmulatorModule, EmulatorModuleTuple, }, qemu::{Hook, MemAccessInfo, Qemu}, sys::TCGTemp, @@ -190,8 +191,6 @@ where I: Unpin, S: Unpin, { - type ModuleAddressFilter = F; - fn pre_qemu_init( &mut self, _emulator_modules: &mut EmulatorModules, @@ -334,6 +333,13 @@ where Hook::Function(guest_trace_error_n_asan::), ); } +} + +impl HasAddressFilter for AsanGuestModule +where + F: AddressFilter, +{ + type ModuleAddressFilter = F; fn address_filter(&self) -> &Self::ModuleAddressFilter { &self.filter diff --git a/libafl_qemu/src/modules/usermode/injections.rs b/libafl_qemu/src/modules/usermode/injections.rs index ca7b933c77..daeee9d81f 100644 --- a/libafl_qemu/src/modules/usermode/injections.rs +++ b/libafl_qemu/src/modules/usermode/injections.rs @@ -24,7 +24,7 @@ use crate::{ elf::EasyElf, emu::EmulatorModules, modules::{ - utils::filters::{NopAddressFilter, NOP_ADDRESS_FILTER}, + utils::filters::{HasAddressFilter, NopAddressFilter, NOP_ADDRESS_FILTER}, EmulatorModule, EmulatorModuleTuple, }, qemu::{ArchExtras, Hook, SyscallHookResult}, @@ -268,8 +268,6 @@ where I: Unpin, S: Unpin, { - type ModuleAddressFilter = NopAddressFilter; - fn post_qemu_init(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -344,6 +342,10 @@ where } } } +} + +impl HasAddressFilter for InjectionModule { + type ModuleAddressFilter = NopAddressFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &NopAddressFilter diff --git a/libafl_qemu/src/modules/usermode/snapshot.rs b/libafl_qemu/src/modules/usermode/snapshot.rs index 01068944d9..1ce4f8a4a9 100644 --- a/libafl_qemu/src/modules/usermode/snapshot.rs +++ b/libafl_qemu/src/modules/usermode/snapshot.rs @@ -24,7 +24,7 @@ use crate::{ emu::EmulatorModules, modules::{ asan::AsanModule, - utils::filters::{NopAddressFilter, NOP_ADDRESS_FILTER}, + utils::filters::{HasAddressFilter, NopAddressFilter, NOP_ADDRESS_FILTER}, EmulatorModule, EmulatorModuleTuple, Range, }, qemu::{Hook, SyscallHookResult}, @@ -698,8 +698,6 @@ where I: Unpin, S: Unpin, { - type ModuleAddressFilter = NopAddressFilter; - fn post_qemu_init(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules) where ET: EmulatorModuleTuple, @@ -737,7 +735,10 @@ where self.reset(qemu); } } +} +impl HasAddressFilter for SnapshotModule { + type ModuleAddressFilter = NopAddressFilter; fn address_filter(&self) -> &Self::ModuleAddressFilter { &NopAddressFilter } diff --git a/libafl_qemu/src/modules/utils/filters.rs b/libafl_qemu/src/modules/utils/filters.rs index ffcb95572a..49baa34d8e 100644 --- a/libafl_qemu/src/modules/utils/filters.rs +++ b/libafl_qemu/src/modules/utils/filters.rs @@ -69,6 +69,64 @@ where } } +/// Offers accessors to modules' address filters. +pub trait HasAddressFilter { + type ModuleAddressFilter: AddressFilter; + #[cfg(feature = "systemmode")] + type ModulePageFilter: PageFilter; + fn address_filter(&self) -> &Self::ModuleAddressFilter; + + fn address_filter_mut(&mut self) -> &mut Self::ModuleAddressFilter; + + fn update_address_filter(&mut self, qemu: Qemu, filter: Self::ModuleAddressFilter) { + *self.address_filter_mut() = filter; + // Necessary because some hooks filter during TB generation. + qemu.flush_jit(); + } + + #[cfg(feature = "systemmode")] + fn page_filter(&self) -> &Self::ModulePageFilter; + #[cfg(feature = "systemmode")] + fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter; + #[cfg(feature = "systemmode")] + fn update_page_filter(&mut self, qemu: Qemu, filter: Self::ModulePageFilter) { + *self.page_filter_mut() = filter; + // Necessary because some hooks filter during TB generation. + qemu.flush_jit(); + } +} + +pub trait HasAddressFilterTuples { + fn allow_address_range_all(&mut self, address_range: Range); + + #[cfg(feature = "systemmode")] + fn allow_page_id_all(&mut self, page_id: GuestPhysAddr); +} + +impl HasAddressFilterTuples for () { + fn allow_address_range_all(&mut self, _address_range: Range) {} + + #[cfg(feature = "systemmode")] + fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {} +} + +impl HasAddressFilterTuples for (Head, Tail) +where + Head: HasAddressFilter, + Tail: HasAddressFilterTuples, +{ + fn allow_address_range_all(&mut self, address_range: Range) { + self.0.address_filter_mut().register(address_range.clone()); + self.1.allow_address_range_all(address_range); + } + + #[cfg(feature = "systemmode")] + fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) { + self.0.page_filter_mut().register(page_id); + self.1.allow_page_id_all(page_id); + } +} + /// An address filter list. /// /// It will allow anything in the registered ranges, and deny anything else.