Avoid using feature flags and env variable to set the same parameter pt.1 emulation_mode (#2512)

* Remove emulation_mode env variable and custom cfg

* Using only the feature flag simplifies things a bit and allow the usage of optional dependencies

* Do not use --all-features on libafl_qemu

* Add missing target_os = "linux"
This commit is contained in:
Marco C. 2024-10-25 15:16:55 +02:00 committed by GitHub
parent e27ec269ce
commit b9e6363826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 225 additions and 198 deletions

View File

@ -130,7 +130,7 @@ jobs:
- uses: Swatinem/rust-cache@v2
with: { shared-key: "ubuntu" }
- name: Run clippy
run: ./scripts/clippy.sh
run: LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/clippy.sh
# --- test embedding the libafl_libfuzzer_runtime library
# Fix me plz
# - name: Test Build libafl_libfuzzer with embed

View File

@ -32,12 +32,7 @@ libafl_targets = { path = "../../../libafl_targets" }
libafl_qemu = { path = "../../../libafl_qemu", features = [
"arm",
"systemmode",
] }
libafl_qemu_sys = { path = "../../../libafl_qemu/libafl_qemu_sys", features = [
"arm",
"systemmode",
] }
], default-features = false }
env_logger = "0.11.5"
log = { version = "0.4.22", features = ["release_max_level_info"] }

View File

@ -30,9 +30,9 @@ use libafl_bolts::{
};
use libafl_qemu::{
config, elf::EasyElf, executor::QemuExecutor, modules::edges::StdEdgeCoverageModuleBuilder,
Emulator, Qemu, QemuExitError, QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
Emulator, GuestPhysAddr, Qemu, QemuExitError, QemuExitReason, QemuRWError, QemuShutdownCause,
Regs,
};
use libafl_qemu_sys::GuestPhysAddr;
use libafl_targets::{edges_map_mut_ptr, EDGES_MAP_DEFAULT_SIZE, MAX_EDGES_FOUND};
pub static mut MAX_INPUT_SIZE: usize = 50;

View File

@ -23,6 +23,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
default = [
"usermode",
"fork",
"build_libgasan",
"build_libqasan",
@ -95,7 +96,7 @@ libafl_bolts = { path = "../libafl_bolts", version = "0.13.2", default-features
"derive",
] }
libafl_targets = { path = "../libafl_targets", version = "0.13.2" }
libafl_qemu_sys = { path = "./libafl_qemu_sys", version = "0.13.2" }
libafl_qemu_sys = { path = "./libafl_qemu_sys", version = "0.13.2", default-features = false }
libafl_derive = { path = "../libafl_derive", version = "0.13.2" }
serde = { workspace = true, default-features = false, features = [

View File

@ -4,8 +4,6 @@ mod host_specific {
#[cfg(not(target_os = "linux"))]
pub fn build() {
// Print a emulation_mode to silence clippy's unexpected cfg on macOS
println!("cargo:rustc-cfg=emulation_mode=\"usermode\"");
println!("cargo:warning=libafl_qemu only builds on Linux hosts");
}
}

View File

@ -16,17 +16,19 @@ void __libafl_qemu_testfile() {}
#[allow(clippy::too_many_lines)]
pub fn build() {
// Note: Unique features are checked in libafl_qemu_sys
println!(r#"cargo::rustc-check-cfg=cfg(emulation_mode, values("usermode", "systemmode"))"#);
println!(
r#"cargo::rustc-check-cfg=cfg(cpu_target, values("arm", "aarch64", "hexagon", "i386", "mips", "ppc", "x86_64"))"#
);
let emulation_mode = if cfg!(feature = "usermode") {
"usermode".to_string()
"usermode"
} else if cfg!(feature = "systemmode") {
"systemmode".to_string()
"systemmode"
} else {
env::var("EMULATION_MODE").unwrap_or_else(|_| "usermode".to_string())
unreachable!(
"The macros `assert_unique_feature` and `assert_at_least_one_feature` in \
`libafl_qemu_sys/build_linux.rs` should panic before this code is reached."
);
};
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
@ -57,23 +59,23 @@ pub fn build() {
let libafl_qemu_impl_hdr = libafl_runtime_dir.join(libafl_qemu_impl_hdr_name);
let libafl_runtime_testfile = out_dir.join("runtime_test.c");
fs::write(&libafl_runtime_testfile, LIBAFL_QEMU_RUNTIME_TEST).expect("Could not write runtime test file");
fs::write(&libafl_runtime_testfile, LIBAFL_QEMU_RUNTIME_TEST)
.expect("Could not write runtime test file");
let mut runtime_test_cc_compiler = cc::Build::new();
runtime_test_cc_compiler.cpp(false)
runtime_test_cc_compiler
.cpp(false)
.include(&libafl_runtime_dir)
.file(&libafl_runtime_testfile);
runtime_test_cc_compiler.try_compile("runtime_test").unwrap();
runtime_test_cc_compiler
.try_compile("runtime_test")
.unwrap();
let runtime_bindings_file = out_dir.join("libafl_qemu_bindings.rs");
let stub_runtime_bindings_file = src_dir.join("runtime/libafl_qemu_stub_bindings.rs");
println!("cargo::rustc-check-cfg=cfg(emulation_mode, values(\"usermode\", \"systemmode\"))");
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=build_linux.rs");
println!("cargo:rerun-if-changed={}", libafl_runtime_dir.display());
@ -99,7 +101,7 @@ pub fn build() {
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))");
let cross_cc = if (emulation_mode == "usermode") && (qemu_asan || qemu_asan_guest) {
let cross_cc = if cfg!(feature = "usermode") && (qemu_asan || qemu_asan_guest) {
// TODO try to autodetect a cross compiler with the arch name (e.g. aarch64-linux-gnu-gcc)
let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| {
println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if the selected cpu target ({cpu_target}) is not the host arch ({}))", env::consts::ARCH);
@ -162,12 +164,12 @@ pub fn build() {
maybe_generate_stub_bindings(
&cpu_target,
&emulation_mode,
emulation_mode,
stub_runtime_bindings_file.as_path(),
runtime_bindings_file.as_path()
runtime_bindings_file.as_path(),
);
if (emulation_mode == "usermode") && (qemu_asan || qemu_asan_guest) {
if cfg!(feature = "usermode") && (qemu_asan || qemu_asan_guest) {
let qasan_dir = Path::new("libqasan");
let qasan_dir = fs::canonicalize(qasan_dir).unwrap();
println!("cargo:rerun-if-changed={}", qasan_dir.display());

View File

@ -23,8 +23,10 @@ features = ["x86_64", "usermode"]
rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["usermode", "x86_64"]
# The following architecture features are mutually exclusive.
x86_64 = [] # build qemu for x86_64 (default)
x86_64 = [] # build qemu for x86_64
i386 = [] # build qemu for i386
arm = [] # build qemu for arm
aarch64 = [] # build qemu for aarch64

View File

@ -14,24 +14,30 @@ macro_rules! assert_unique_feature {
}
}
pub fn build() {
// Make sure that exactly one qemu mode is set
assert_unique_feature!("usermode", "systemmode");
let emulation_mode = if cfg!(feature = "usermode") {
"usermode".to_string()
} else if cfg!(feature = "systemmode") {
"systemmode".to_string()
} else {
env::var("EMULATION_MODE").unwrap_or_else(|_| {
println!(
"cargo:warning=No emulation mode feature enabled or EMULATION_MODE env specified for libafl_qemu, supported: usermode, systemmmode - defaulting to usermode"
);
"usermode".to_string()
})
#[macro_export]
macro_rules! assert_at_least_one_feature {
($($feature:literal),+) => {
#[cfg(not(any($(feature = $feature),+)))]
compile_error!(concat!("At least one of the following features must be enabled:", $(" ", $feature),+));
};
}
pub fn build() {
// Make sure that at most one qemu mode is set
assert_unique_feature!("usermode", "systemmode");
// Make sure that at least one qemu mode is set
assert_at_least_one_feature!("usermode", "systemmode");
let emulation_mode = if cfg!(feature = "usermode") {
"usermode"
} else if cfg!(feature = "systemmode") {
"systemmode"
} else {
unreachable!(
"The above macros, `assert_unique_feature` and `assert_at_least_one_feature`, should \
panic before this code is reached."
);
};
println!("cargo::rustc-check-cfg=cfg(emulation_mode, values(\"usermode\", \"systemmode\"))");
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
// Make sure we have at most one architecutre feature set
// Else, we default to `x86_64` - having a default makes CI easier :)
@ -100,7 +106,7 @@ pub fn build() {
// If the bindings are built and differ from the current stub, replace it with the freshly generated bindings
maybe_generate_stub_bindings(
&cpu_target,
&emulation_mode,
emulation_mode,
stub_bindings_file.as_path(),
bindings_file.as_path(),
);

View File

@ -17,14 +17,14 @@ use strum_macros::EnumIter;
mod bindings;
pub use bindings::*;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
mod usermode;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub use usermode::*;
// #[cfg(emulation_mode = "systemmode")]
// #[cfg(feature = "systemmode")]
// mod systemmode;
// #[cfg(emulation_mode = "systemmode")]
// #[cfg(feature = "systemmode")]
// pub use systemmode::*;
/// Safe linking with of extern "C" functions.

View File

@ -104,6 +104,8 @@ impl IntoPy<PyObject> for MmapPerms {
n.into_py(py)
}
}
#[cfg(target_os = "linux")]
impl From<libafl_mapinfo> for MapInfo {
fn from(map_info: libafl_mapinfo) -> Self {
let path: Option<String> = if map_info.path.is_null() {

View File

@ -12,7 +12,7 @@ use libafl::{
};
use libafl_bolts::AsSlice;
use libafl_qemu_sys::GuestAddr;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use libafl_qemu_sys::GuestPhysAddr;
use libc::c_uint;
use num_enum::TryFromPrimitive;
@ -457,7 +457,7 @@ where
}
// Auto page filtering if option is enabled
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
if emu.driver_mut().allow_page_on_start() {
if let Some(page_id) = qemu.current_cpu().unwrap().current_paging_id() {
emu.modules_mut().modules_mut().allow_page_id_all(page_id);
@ -566,13 +566,13 @@ where
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[derive(Debug, Clone)]
pub struct PageAllowCommand {
page_id: GuestPhysAddr,
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl<CM, ED, ET, S, SM> IsCommand<CM, ED, ET, S, SM> for PageAllowCommand
where
ET: EmulatorModuleTuple<S>,
@ -760,7 +760,7 @@ impl Display for AddressAllowCommand {
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl Display for PageAllowCommand {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Allowed page: {:?}", self.page_id)

View File

@ -6,7 +6,7 @@ use libafl::{
};
use libafl_bolts::tuples::{tuple_list, Prepend};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use crate::FastSnapshotManager;
use crate::{
command::{CommandManager, NopCommandManager, StdCommandManager},
@ -53,7 +53,7 @@ where
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl<S> EmulatorBuilder<StdCommandManager<S>, StdEmulatorDriver, (), S, StdSnapshotManager>
where
S: State + HasExecutions + Unpin,
@ -73,7 +73,7 @@ where
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl<S> EmulatorBuilder<StdCommandManager<S>, StdEmulatorDriver, (), S, StdSnapshotManager>
where
S: State + HasExecutions + Unpin,

View File

@ -117,7 +117,7 @@ pub struct StdEmulatorDriver {
input_location: OnceCell<InputLocation>,
#[builder(default = true)]
hooks_locked: bool,
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[builder(default = false)]
allow_page_on_start: bool,
#[cfg(feature = "x86_64")]
@ -147,7 +147,7 @@ impl StdEmulatorDriver {
was_locked
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub fn allow_page_on_start(&self) -> bool {
self.allow_page_on_start
}

View File

@ -1,19 +1,19 @@
#![allow(clippy::missing_transmute_annotations)]
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use std::ptr::addr_of_mut;
use std::{fmt::Debug, marker::PhantomData, mem::transmute, pin::Pin, ptr};
use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple};
use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize, TCGTemp};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use crate::qemu::{
closure_post_syscall_hook_wrapper, closure_pre_syscall_hook_wrapper,
func_post_syscall_hook_wrapper, func_pre_syscall_hook_wrapper, PostSyscallHook,
PostSyscallHookId, PreSyscallHook, PreSyscallHookId, SyscallHookResult,
};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use crate::qemu::{
CrashHookClosure, CrashHookFn, PostSyscallHookClosure, PostSyscallHookFn,
PreSyscallHookClosure, PreSyscallHookFn,
@ -68,7 +68,7 @@ macro_rules! hook_to_repr {
static mut EMULATOR_TOOLS: *mut () = ptr::null_mut();
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub extern "C" fn crash_hook_wrapper<ET, S>(target_sig: i32)
where
ET: EmulatorModuleTuple<S>,
@ -126,13 +126,13 @@ where
new_thread_hooks: Vec<Pin<Box<(NewThreadHookId, FatPtr)>>>,
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pre_syscall_hooks: Vec<Pin<Box<(PreSyscallHookId, FatPtr)>>>,
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
post_syscall_hooks: Vec<Pin<Box<(PostSyscallHookId, FatPtr)>>>,
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
crash_hooks: Vec<HookRepr>,
phantom: PhantomData<(ET, S)>,
@ -159,13 +159,13 @@ where
new_thread_hooks: Vec::new(),
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pre_syscall_hooks: Vec::new(),
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
post_syscall_hooks: Vec::new(),
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
crash_hooks: Vec::new(),
}
}
@ -761,7 +761,7 @@ where
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl<ET, S> EmulatorHooks<ET, S>
where
ET: EmulatorModuleTuple<S>,
@ -1210,7 +1210,7 @@ where
}
/// Usermode-only high-level functions
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl<ET, S> EmulatorModules<ET, S>
where
ET: EmulatorModuleTuple<S>,

View File

@ -35,14 +35,14 @@ pub use drivers::*;
mod snapshot;
pub use snapshot::*;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
mod usermode;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub use usermode::*;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
mod systemmode;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub use systemmode::*;
#[derive(Clone, Copy)]

View File

@ -4,9 +4,9 @@ use core::{
fmt::{self, Debug, Formatter},
time::Duration,
};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use std::ptr;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use std::sync::atomic::{AtomicBool, Ordering};
use libafl::{
@ -31,13 +31,13 @@ use libafl_bolts::{
os::unix_signals::{ucontext_t, Signal},
tuples::RefIndexable,
};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use libafl_qemu_sys::libafl_exit_request_timeout;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use libafl_qemu_sys::libafl_qemu_handle_crash;
use libc::siginfo_t;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use crate::EmulatorModules;
use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver};
@ -56,7 +56,7 @@ where
/// # Safety
///
/// This should be used as a crash handler, and nothing else.
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
unsafe fn inproc_qemu_crash_handler<ET, S>(
signal: Signal,
info: &mut siginfo_t,
@ -79,7 +79,7 @@ unsafe fn inproc_qemu_crash_handler<ET, S>(
libafl_qemu_handle_crash(signal as i32, info, puc);
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub(crate) static BREAK_ON_TMOUT: AtomicBool = AtomicBool::new(false);
/// # Safety
@ -102,7 +102,7 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, OF, S, Z>(
<<E as UsesState>::State as HasSolutions>::Solutions: Corpus<Input = E::Input>, //delete me
<<<E as UsesState>::State as HasCorpus>::Corpus as Corpus>::Input: Clone, //delete me
{
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
{
if BREAK_ON_TMOUT.load(Ordering::Acquire) {
libafl_exit_request_timeout();
@ -116,7 +116,7 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, OF, S, Z>(
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
// run modules' crash callback
if let Some(emulator_modules) = EmulatorModules::<ET, S>::emulator_modules_mut() {
@ -176,7 +176,7 @@ where
harness_fn, emulator, observers, fuzzer, state, event_mgr, timeout,
)?;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
inner.inprocess_hooks_mut().crash_handler =
inproc_qemu_crash_handler::<ET, S> as *const c_void;
@ -220,7 +220,7 @@ where
&self.inner
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub fn break_on_timeout(&mut self) {
BREAK_ON_TMOUT.store(true, Ordering::Release);
}

View File

@ -45,7 +45,7 @@ pub mod command;
pub mod sync_exit;
pub use libafl_qemu_sys::{GuestAddr, MmapPerms};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub use libafl_qemu_sys::{GuestPhysAddr, GuestVirtAddr};
#[must_use]
@ -89,10 +89,10 @@ pub fn python_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
}
m.add_submodule(&mmapm)?;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
m.add_class::<sys::MapInfo>()?;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
m.add_class::<GuestMaps>()?;
m.add_class::<SyscallHookResult>()?;

View File

@ -10,7 +10,7 @@ use libafl_bolts::tuples::{Handle, Handled, MatchFirstType, MatchNameRef};
use libafl_qemu_sys::GuestAddr;
use thread_local::ThreadLocal;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use crate::modules::{NopPageFilter, NOP_PAGE_FILTER};
use crate::{
capstone,
@ -300,14 +300,14 @@ where
if let Some(h) = emulator_modules.modules().match_first_type::<Self>() {
#[allow(unused_mut)]
let mut code = {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
unsafe {
std::slice::from_raw_parts(qemu.g2h(pc), 512)
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
&mut [0; 512]
};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.read_mem(pc, code)
}; // TODO handle faults
@ -342,11 +342,11 @@ where
iaddr += insn.bytes().len() as GuestAddr;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
unsafe {
code = std::slice::from_raw_parts(qemu.g2h(iaddr), 512);
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.read_mem(pc, code);
} // TODO handle faults
@ -390,7 +390,7 @@ where
T: CallTraceCollectorTuple + Debug,
{
type ModuleAddressFilter = StdAddressFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = NopPageFilter;
fn init_module<ET>(&self, emulator_modules: &mut EmulatorModules<ET, S>)
@ -445,12 +445,12 @@ where
&mut self.filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&NopPageFilter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
}

View File

@ -1,7 +1,7 @@
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use std::ptr::addr_of_mut;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use capstone::{arch::BuildsCapstone, Capstone, InsnDetail};
use hashbrown::HashMap;
use libafl::{inputs::UsesInput, HasMetadata};
@ -14,9 +14,9 @@ pub use libafl_targets::{
};
use serde::{Deserialize, Serialize};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use crate::modules::{NopPageFilter, NOP_PAGE_FILTER};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use crate::{capstone, qemu::ArchExtras, CallingConvention, Qemu};
use crate::{
emu::EmulatorModules,
@ -74,7 +74,7 @@ where
S: Unpin + UsesInput + HasMetadata,
{
type ModuleAddressFilter = StdAddressFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = NopPageFilter;
fn first_exec<ET>(&mut self, emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
@ -98,12 +98,12 @@ where
&mut self.address_filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&NopPageFilter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
}
@ -137,7 +137,7 @@ where
S: Unpin + UsesInput + HasMetadata,
{
type ModuleAddressFilter = StdAddressFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = NopPageFilter;
const HOOKS_DO_SIDE_EFFECTS: bool = false;
@ -163,12 +163,12 @@ where
&mut self.address_filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&NopPageFilter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
}
@ -247,14 +247,14 @@ pub extern "C" fn trace_cmp8_cmplog(_: *const (), id: u64, v0: u64, v1: u64) {
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
#[derive(Debug)]
pub struct CmpLogRoutinesModule {
address_filter: StdAddressFilter,
cs: Capstone,
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl CmpLogRoutinesModule {
#[must_use]
pub fn new(address_filter: StdAddressFilter) -> Self {
@ -326,14 +326,14 @@ impl CmpLogRoutinesModule {
if let Some(h) = emulator_modules.get::<Self>() {
#[allow(unused_mut)]
let mut code = {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
unsafe {
std::slice::from_raw_parts(qemu.g2h(pc), 512)
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
&mut [0; 512]
};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.read_mem(pc, code)
}; // TODO handle faults
@ -370,11 +370,11 @@ impl CmpLogRoutinesModule {
iaddr += insn.bytes().len() as GuestAddr;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
unsafe {
code = std::slice::from_raw_parts(qemu.g2h(iaddr), 512);
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.read_mem(pc, code);
} // TODO handle faults
@ -385,13 +385,13 @@ impl CmpLogRoutinesModule {
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl<S> EmulatorModule<S> for CmpLogRoutinesModule
where
S: Unpin + UsesInput,
{
type ModuleAddressFilter = StdAddressFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = NopPageFilter;
fn first_exec<ET>(&mut self, emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
@ -413,12 +413,12 @@ where
&mut self.address_filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&NopPageFilter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
&mut NopPageFilter
}

View File

@ -1,4 +1,4 @@
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use std::ptr::addr_of_mut;
use std::{path::PathBuf, sync::Mutex};
@ -9,7 +9,7 @@ use libafl_targets::drcov::{DrCovBasicBlock, DrCovWriter};
use rangemap::RangeMap;
use serde::{Deserialize, Serialize};
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use crate::modules::{NopPageFilter, NOP_PAGE_FILTER};
use crate::{
emu::EmulatorModules,
@ -260,7 +260,7 @@ where
S: Unpin + UsesInput + HasMetadata,
{
type ModuleAddressFilter = F;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = NopPageFilter;
fn init_module<ET>(&self, emulator_modules: &mut EmulatorModules<ET, S>)
@ -274,7 +274,7 @@ where
);
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
fn first_exec<ET>(&mut self, emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
where
ET: EmulatorModuleTuple<S>,
@ -304,7 +304,7 @@ where
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn first_exec<ET>(&mut self, _emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
where
ET: EmulatorModuleTuple<S>,
@ -345,12 +345,12 @@ where
&mut self.filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&NopPageFilter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
unsafe { addr_of_mut!(NOP_PAGE_FILTER).as_mut().unwrap().get_mut() }
}

View File

@ -4,7 +4,7 @@ use hashbrown::{hash_map::Entry, HashMap};
use libafl::{inputs::UsesInput, observers::VariableLengthMapObserver, HasMetadata};
use libafl_bolts::Error;
use libafl_qemu_sys::GuestAddr;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
use libafl_qemu_sys::GuestPhysAddr;
use libafl_targets::EDGES_MAP;
use serde::{Deserialize, Serialize};
@ -368,7 +368,7 @@ pub struct EdgeCoverageModule<AF, PF, V> {
variant: V,
address_filter: AF,
// we only use it in system mode at the moment.
#[cfg_attr(not(emulation_mode = "systemmode"), allow(dead_code))]
#[cfg_attr(not(feature = "systemmode"), allow(dead_code))]
page_filter: PF,
use_hitcounts: bool,
use_jit: bool,
@ -514,13 +514,13 @@ where
AF: AddressFilter,
PF: PageFilter,
{
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
#[must_use]
pub fn must_instrument(&self, addr: GuestAddr) -> bool {
self.address_filter.allowed(&addr)
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[must_use]
pub fn must_instrument(&self, addr: GuestAddr, page_id: Option<GuestPhysAddr>) -> bool {
if let Some(page_id) = page_id {
@ -541,7 +541,7 @@ where
const HOOKS_DO_SIDE_EFFECTS: bool = V::DO_SIDE_EFFECTS;
type ModuleAddressFilter = AF;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter = PF;
fn first_exec<ET>(&mut self, emulator_modules: &mut EmulatorModules<ET, S>, _state: &mut S)
@ -569,12 +569,12 @@ where
&mut self.address_filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter {
&self.page_filter
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter {
&mut self.page_filter
}
@ -600,14 +600,14 @@ where
assert_ne!(*addr_of!(LIBAFL_QEMU_EDGES_MAP_SIZE_PTR), ptr::null_mut());
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
if !module.must_instrument(src) && !module.must_instrument(dest) {
return None;
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
{
let paging_id = emulator_modules
.qemu()
@ -678,12 +678,12 @@ where
V: EdgeCoverageVariant<AF, PF>,
{
if let Some(module) = emulator_modules.get::<EdgeCoverageModule<AF, PF, V>>() {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
if !module.must_instrument(src) && !module.must_instrument(dest) {
return None;
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
{
let paging_id = emulator_modules
.qemu()
@ -744,13 +744,13 @@ where
{
// first check if we should filter
if let Some(module) = emulator_modules.get::<EdgeCoverageModule<AF, PF, V>>() {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
if !module.must_instrument(pc) {
return None;
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
{
let page_id = emulator_modules
.qemu()

View File

@ -6,14 +6,14 @@ use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple};
use libafl_bolts::tuples::{MatchFirstType, SplitBorrowExtractFirstType};
use libafl_qemu_sys::{GuestAddr, GuestPhysAddr};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub mod usermode;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub use usermode::*;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
pub mod systemmode;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[allow(unused_imports)]
pub use systemmode::*;
@ -45,7 +45,7 @@ where
{
type ModuleAddressFilter: AddressFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
type ModulePageFilter: PageFilter;
const HOOKS_DO_SIDE_EFFECTS: bool = true;
@ -113,11 +113,11 @@ where
qemu.flush_jit();
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter(&self) -> &Self::ModulePageFilter;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn page_filter_mut(&mut self) -> &mut Self::ModulePageFilter;
#[cfg(emulation_mode = "systemmode")]
#[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.
@ -171,7 +171,7 @@ where
fn allow_address_range_all(&mut self, address_range: Range<GuestAddr>);
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr);
}
@ -222,7 +222,7 @@ where
fn allow_address_range_all(&mut self, _address_range: Range<GuestAddr>) {}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn allow_page_id_all(&mut self, _page_id: GuestPhysAddr) {}
}
@ -294,7 +294,7 @@ where
self.1.allow_address_range_all(address_range);
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn allow_page_id_all(&mut self, page_id: GuestPhysAddr) {
self.0.page_filter_mut().register(page_id.clone());
self.1.allow_page_id_all(page_id)
@ -425,11 +425,11 @@ pub struct PageFilterVec {
registered_pages: HashSet<GuestPhysAddr>,
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[derive(Clone, Debug)]
pub struct StdPageFilter(FilterList<PageFilterVec>);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub type StdPageFilter = NopPageFilter;
impl Default for PageFilterVec {
@ -440,7 +440,7 @@ impl Default for PageFilterVec {
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl Default for StdPageFilter {
fn default() -> Self {
Self(FilterList::None)
@ -462,7 +462,7 @@ impl PageFilter for PageFilterVec {
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl PageFilter for StdPageFilter {
fn register(&mut self, page_id: GuestPhysAddr) {
self.0.register(page_id);
@ -517,7 +517,7 @@ impl PageFilter for NopPageFilter {
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
static mut NOP_ADDRESS_FILTER: UnsafeCell<NopAddressFilter> = UnsafeCell::new(NopAddressFilter);
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
static mut NOP_PAGE_FILTER: UnsafeCell<NopPageFilter> = UnsafeCell::new(NopPageFilter);

View File

@ -16,7 +16,7 @@ use crate::{Qemu, QemuInitError};
pub(super) static QEMU_CONFIG: OnceLock<QemuConfig> = OnceLock::new();
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[derive(Debug, strum_macros::Display, Clone)]
#[strum(prefix = "-accel ", serialize_all = "lowercase")]
pub enum Accelerator {
@ -100,20 +100,20 @@ pub enum Monitor {
/// Set the directory for the BIOS, VGA BIOS and keymaps.
/// Corresponds to the `-L` option of QEMU.
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[derive(Debug, Clone)]
pub struct Bios {
path: PathBuf,
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl Display for Bios {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "-L {}", self.path.to_str().unwrap())
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl<R: AsRef<Path>> From<R> for Bios {
fn from(path: R) -> Self {
Self {
@ -122,20 +122,20 @@ impl<R: AsRef<Path>> From<R> for Bios {
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[derive(Debug, Clone)]
pub struct Kernel {
path: PathBuf,
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl Display for Kernel {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "-kernel {}", self.path.to_str().unwrap())
}
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
impl<R: AsRef<Path>> From<R> for Kernel {
fn from(path: R) -> Self {
Self {
@ -281,20 +281,20 @@ impl From<bool> for VgaPci {
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
#[derive(Debug, Clone)]
pub struct Program {
path: PathBuf,
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl Display for Program {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.path.to_str().unwrap())
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl<R: AsRef<Path>> From<R> for Program {
fn from(path: R) -> Self {
Self {
@ -314,15 +314,15 @@ impl<R: AsRef<Path>> From<R> for Program {
its visibility is pub(crate)"))]
#[getset(get = "pub")]
pub struct QemuConfig {
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[builder(default, setter(strip_option))]
accelerator: Option<Accelerator>,
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[builder(default, setter(strip_option, into))]
bios: Option<Bios>,
#[builder(default, setter(into))]
drives: Vec<Drive>,
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[builder(default, setter(strip_option, into))]
kernel: Option<Kernel>,
#[builder(default, setter(strip_option, into))]
@ -345,7 +345,7 @@ pub struct QemuConfig {
vga_pci: Option<VgaPci>,
#[builder(default, setter(strip_option, into))]
start_cpu: Option<StartCPU>,
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
#[builder(setter(into))]
program: Program,
} // Adding something here? Please leave Program as the last field
@ -380,7 +380,7 @@ mod test {
use super::*;
#[test]
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
fn usermode() {
let program = "/bin/pwd";
let qemu = Qemu::builder().program("/bin/pwd").build().unwrap();
@ -398,7 +398,7 @@ mod test {
}
#[test]
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
fn accelerator_kvm_to_string() {
let accel = Accelerator::Kvm;
assert_eq!(accel.to_string(), "-accel kvm");

View File

@ -6,7 +6,7 @@
use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr};
use libafl::{executors::hooks::inprocess::inprocess_get_state, inputs::UsesInput};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
use libafl_qemu_sys::libafl_dump_core_hook;
use libafl_qemu_sys::{CPUArchStatePtr, CPUStatePtr, FatPtr, GuestAddr, GuestUsize};
#[cfg(feature = "python")]
@ -377,7 +377,7 @@ create_hook_id!(Backdoor, libafl_qemu_remove_backdoor_hook, true);
create_wrapper!(backdoor, (cpu: CPUArchStatePtr, pc: GuestAddr));
// Pre-syscall hook wrappers
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_hook_types!(
PreSyscall,
fn(
@ -421,9 +421,9 @@ create_hook_types!(
GuestAddr,
) -> SyscallHookResult
);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_hook_id!(PreSyscall, libafl_qemu_remove_pre_syscall_hook, false);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_wrapper!(
pre_syscall,
(
@ -441,7 +441,7 @@ create_wrapper!(
);
// Post-syscall hook wrappers
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_hook_types!(
PostSyscall,
fn(
@ -488,9 +488,9 @@ create_hook_types!(
GuestAddr,
) -> GuestAddr
);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_hook_id!(PostSyscall, libafl_qemu_remove_post_syscall_hook, false);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
create_wrapper!(
post_syscall,
(
@ -723,9 +723,9 @@ create_exec_wrapper!(cmp, (id: u64, v0: u32, v1: u32), 2, 4, CmpHookId);
create_exec_wrapper!(cmp, (id: u64, v0: u64, v1: u64), 3, 4, CmpHookId);
// Crash hook wrappers
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub type CrashHookFn<ET, S> = fn(&mut EmulatorModules<ET, S>, i32);
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub type CrashHookClosure<ET, S> = Box<dyn FnMut(&mut EmulatorModules<ET, S>, i32)>;
/// The thin wrapper around QEMU hooks.
@ -969,7 +969,7 @@ impl QemuHooks {
}
}
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
impl QemuHooks {
#[allow(clippy::type_complexity)]
pub fn add_pre_syscall_hook<T: Into<HookData>>(

View File

@ -34,14 +34,14 @@ use crate::{GuestAddrKind, GuestReg, Regs};
pub mod config;
use config::{QemuConfig, QemuConfigBuilder, QEMU_CONFIG};
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
mod usermode;
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
pub use usermode::*;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
mod systemmode;
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
#[allow(unused_imports)]
pub use systemmode::*;
@ -603,7 +603,7 @@ impl Qemu {
libafl_qemu_init(argc, argv.as_ptr() as *mut *mut ::std::os::raw::c_char);
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
libafl_qemu_sys::syx_snapshot_init(true);
libc::atexit(qemu_cleanup_atexit);
@ -715,7 +715,7 @@ impl Qemu {
},
libafl_qemu_sys::libafl_exit_reason_kind_SYNC_EXIT => QemuExitReason::SyncExit,
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
libafl_qemu_sys::libafl_exit_reason_kind_TIMEOUT => QemuExitReason::Timeout,
_ => return Err(QemuExitError::UnknownKind),
@ -1030,12 +1030,12 @@ impl QemuMemoryChunk {
match self.addr {
GuestAddrKind::Physical(hwaddr) => {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
// For now the default behaviour is to fall back to virtual addresses
qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced)?;
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.read_phys_mem(hwaddr, output_sliced);
}
@ -1064,12 +1064,12 @@ impl QemuMemoryChunk {
match self.addr {
GuestAddrKind::Physical(hwaddr) => {
#[cfg(emulation_mode = "usermode")]
#[cfg(feature = "usermode")]
{
// For now the default behaviour is to fall back to virtual addresses
qemu.write_mem(hwaddr.try_into().unwrap(), input_sliced)?;
}
#[cfg(emulation_mode = "systemmode")]
#[cfg(feature = "systemmode")]
unsafe {
qemu.write_phys_mem(hwaddr, input_sliced);
}

View File

@ -3,16 +3,18 @@
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR/.." || exit 1
CLIPPY_CMD="RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace"
CLIPPY_CMD="RUST_BACKTRACE=full cargo +nightly clippy --no-deps --tests --examples --benches"
RUSTC_FLAGS="-Z macro-backtrace"
set -e
# Function to run Clippy on a single directory
run_clippy() {
local dir="$1"
local features="$2"
echo "Running Clippy on $dir"
pushd "$dir" || return 1
eval "$CLIPPY_CMD"
eval "$CLIPPY_CMD ${features:+"$features"} -- $RUSTC_FLAGS"
popd || return 1
}
@ -32,6 +34,11 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
)
fi
# Do not use --all-features for the following projects
NO_ALL_FEATURES=(
"libafl_qemu"
)
if [ "$#" -eq 0 ]; then
# No arguments provided, run on all projects
PROJECTS=("${ALL_PROJECTS[@]}")
@ -41,14 +48,18 @@ else
fi
# First run it on all
eval "$CLIPPY_CMD"
eval "$CLIPPY_CMD --workspace -- $RUSTC_FLAGS"
# Loop through each project and run Clippy
for project in "${PROJECTS[@]}"; do
# Trim leading and trailing whitespace
project=$(echo "$project" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
features="--all-features"
if [[ " ${NO_ALL_FEATURES[*]} " =~ ${project} ]]; then
features="--features=clippy"
fi
if [ -d "$project" ]; then
run_clippy "$project"
run_clippy "$project" $features
else
echo "Warning: Directory $project does not exist. Skipping."
fi

View File

@ -21,7 +21,10 @@ if "LLVM_CONFIG" not in os.environ:
command = (
"DOCS_RS=1 cargo hack check --workspace --each-feature --clean-per-run "
"--exclude-features=prelude,python,sancov_pcguard_edges,arm,aarch64,i386,be,systemmode,whole_archive "
"--no-dev-deps --exclude libafl_libfuzzer --print-command-list"
"--no-dev-deps --exclude libafl_libfuzzer --exclude libafl_qemu --exclude libafl_qemu_sys --print-command-list;"
"DOCS_RS=1 cargo hack check -p libafl_qemu -p libafl_qemu_sys --each-feature --clean-per-run "
"--exclude-features=prelude,python,sancov_pcguard_edges,arm,aarch64,i386,be,systemmode,whole_archive "
"--no-dev-deps --features usermode --print-command-list"
)
# Run the command and capture the output
@ -36,6 +39,13 @@ for task in output[
]:
print("Running ", task)
print(os.environ)
if ("utils/libafl_jumper/Cargo.toml" in task
and "--no-default-features" in task
and "--features" not in task):
# ignore libafl_jumper no std
continue
if "libafl_frida" in task:
# DOCS_RS is needed for libafl_frida to build without auto-download feature
cargo_check = subprocess.check_output(