Skip to content

Commit b9e6363

Browse files
authored
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"
1 parent e27ec26 commit b9e6363

27 files changed

+220
-193
lines changed

.github/workflows/build_and_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ jobs:
130130
- uses: Swatinem/rust-cache@v2
131131
with: { shared-key: "ubuntu" }
132132
- name: Run clippy
133-
run: ./scripts/clippy.sh
133+
run: LLVM_CONFIG=llvm-config-${{env.MAIN_LLVM_VERSION}} ./scripts/clippy.sh
134134
# --- test embedding the libafl_libfuzzer_runtime library
135135
# Fix me plz
136136
# - name: Test Build libafl_libfuzzer with embed

fuzzers/full_system/qemu_baremetal/Cargo.toml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,7 @@ libafl_targets = { path = "../../../libafl_targets" }
3232
libafl_qemu = { path = "../../../libafl_qemu", features = [
3333
"arm",
3434
"systemmode",
35-
] }
36-
libafl_qemu_sys = { path = "../../../libafl_qemu/libafl_qemu_sys", features = [
37-
"arm",
38-
"systemmode",
39-
] }
40-
35+
], default-features = false }
4136
env_logger = "0.11.5"
4237
log = { version = "0.4.22", features = ["release_max_level_info"] }
4338

fuzzers/full_system/qemu_baremetal/src/fuzzer_low_level.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ use libafl_bolts::{
3030
};
3131
use libafl_qemu::{
3232
config, elf::EasyElf, executor::QemuExecutor, modules::edges::StdEdgeCoverageModuleBuilder,
33-
Emulator, Qemu, QemuExitError, QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
33+
Emulator, GuestPhysAddr, Qemu, QemuExitError, QemuExitReason, QemuRWError, QemuShutdownCause,
34+
Regs,
3435
};
35-
use libafl_qemu_sys::GuestPhysAddr;
3636
use libafl_targets::{edges_map_mut_ptr, EDGES_MAP_DEFAULT_SIZE, MAX_EDGES_FOUND};
3737

3838
pub static mut MAX_INPUT_SIZE: usize = 50;

libafl_qemu/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rustdoc-args = ["--cfg", "docsrs"]
2323

2424
[features]
2525
default = [
26+
"usermode",
2627
"fork",
2728
"build_libgasan",
2829
"build_libqasan",
@@ -95,7 +96,7 @@ libafl_bolts = { path = "../libafl_bolts", version = "0.13.2", default-features
9596
"derive",
9697
] }
9798
libafl_targets = { path = "../libafl_targets", version = "0.13.2" }
98-
libafl_qemu_sys = { path = "./libafl_qemu_sys", version = "0.13.2" }
99+
libafl_qemu_sys = { path = "./libafl_qemu_sys", version = "0.13.2", default-features = false }
99100
libafl_derive = { path = "../libafl_derive", version = "0.13.2" }
100101

101102
serde = { workspace = true, default-features = false, features = [

libafl_qemu/build.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ mod host_specific {
44

55
#[cfg(not(target_os = "linux"))]
66
pub fn build() {
7-
// Print a emulation_mode to silence clippy's unexpected cfg on macOS
8-
println!("cargo:rustc-cfg=emulation_mode=\"usermode\"");
97
println!("cargo:warning=libafl_qemu only builds on Linux hosts");
108
}
119
}

libafl_qemu/build_linux.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@ void __libafl_qemu_testfile() {}
1616
#[allow(clippy::too_many_lines)]
1717
pub fn build() {
1818
// Note: Unique features are checked in libafl_qemu_sys
19-
println!(r#"cargo::rustc-check-cfg=cfg(emulation_mode, values("usermode", "systemmode"))"#);
2019
println!(
2120
r#"cargo::rustc-check-cfg=cfg(cpu_target, values("arm", "aarch64", "hexagon", "i386", "mips", "ppc", "x86_64"))"#
2221
);
2322

2423
let emulation_mode = if cfg!(feature = "usermode") {
25-
"usermode".to_string()
24+
"usermode"
2625
} else if cfg!(feature = "systemmode") {
27-
"systemmode".to_string()
26+
"systemmode"
2827
} else {
29-
env::var("EMULATION_MODE").unwrap_or_else(|_| "usermode".to_string())
28+
unreachable!(
29+
"The macros `assert_unique_feature` and `assert_at_least_one_feature` in \
30+
`libafl_qemu_sys/build_linux.rs` should panic before this code is reached."
31+
);
3032
};
3133

3234
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
@@ -57,23 +59,23 @@ pub fn build() {
5759
let libafl_qemu_impl_hdr = libafl_runtime_dir.join(libafl_qemu_impl_hdr_name);
5860

5961
let libafl_runtime_testfile = out_dir.join("runtime_test.c");
60-
fs::write(&libafl_runtime_testfile, LIBAFL_QEMU_RUNTIME_TEST).expect("Could not write runtime test file");
62+
fs::write(&libafl_runtime_testfile, LIBAFL_QEMU_RUNTIME_TEST)
63+
.expect("Could not write runtime test file");
6164

6265
let mut runtime_test_cc_compiler = cc::Build::new();
6366

64-
runtime_test_cc_compiler.cpp(false)
67+
runtime_test_cc_compiler
68+
.cpp(false)
6569
.include(&libafl_runtime_dir)
6670
.file(&libafl_runtime_testfile);
6771

68-
runtime_test_cc_compiler.try_compile("runtime_test").unwrap();
72+
runtime_test_cc_compiler
73+
.try_compile("runtime_test")
74+
.unwrap();
6975

7076
let runtime_bindings_file = out_dir.join("libafl_qemu_bindings.rs");
7177
let stub_runtime_bindings_file = src_dir.join("runtime/libafl_qemu_stub_bindings.rs");
7278

73-
println!("cargo::rustc-check-cfg=cfg(emulation_mode, values(\"usermode\", \"systemmode\"))");
74-
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
75-
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
76-
7779
println!("cargo:rerun-if-changed=build.rs");
7880
println!("cargo:rerun-if-changed=build_linux.rs");
7981
println!("cargo:rerun-if-changed={}", libafl_runtime_dir.display());
@@ -99,7 +101,7 @@ pub fn build() {
99101
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
100102
println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))");
101103

102-
let cross_cc = if (emulation_mode == "usermode") && (qemu_asan || qemu_asan_guest) {
104+
let cross_cc = if cfg!(feature = "usermode") && (qemu_asan || qemu_asan_guest) {
103105
// TODO try to autodetect a cross compiler with the arch name (e.g. aarch64-linux-gnu-gcc)
104106
let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| {
105107
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() {
162164

163165
maybe_generate_stub_bindings(
164166
&cpu_target,
165-
&emulation_mode,
167+
emulation_mode,
166168
stub_runtime_bindings_file.as_path(),
167-
runtime_bindings_file.as_path()
169+
runtime_bindings_file.as_path(),
168170
);
169171

170-
if (emulation_mode == "usermode") && (qemu_asan || qemu_asan_guest) {
172+
if cfg!(feature = "usermode") && (qemu_asan || qemu_asan_guest) {
171173
let qasan_dir = Path::new("libqasan");
172174
let qasan_dir = fs::canonicalize(qasan_dir).unwrap();
173175
println!("cargo:rerun-if-changed={}", qasan_dir.display());

libafl_qemu/libafl_qemu_sys/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ features = ["x86_64", "usermode"]
2323
rustdoc-args = ["--cfg", "docsrs"]
2424

2525
[features]
26+
default = ["usermode", "x86_64"]
27+
2628
# The following architecture features are mutually exclusive.
27-
x86_64 = [] # build qemu for x86_64 (default)
29+
x86_64 = [] # build qemu for x86_64
2830
i386 = [] # build qemu for i386
2931
arm = [] # build qemu for arm
3032
aarch64 = [] # build qemu for aarch64

libafl_qemu/libafl_qemu_sys/build_linux.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,30 @@ macro_rules! assert_unique_feature {
1414
}
1515
}
1616

17+
#[macro_export]
18+
macro_rules! assert_at_least_one_feature {
19+
($($feature:literal),+) => {
20+
#[cfg(not(any($(feature = $feature),+)))]
21+
compile_error!(concat!("At least one of the following features must be enabled:", $(" ", $feature),+));
22+
};
23+
}
24+
1725
pub fn build() {
18-
// Make sure that exactly one qemu mode is set
26+
// Make sure that at most one qemu mode is set
1927
assert_unique_feature!("usermode", "systemmode");
28+
// Make sure that at least one qemu mode is set
29+
assert_at_least_one_feature!("usermode", "systemmode");
30+
2031
let emulation_mode = if cfg!(feature = "usermode") {
21-
"usermode".to_string()
32+
"usermode"
2233
} else if cfg!(feature = "systemmode") {
23-
"systemmode".to_string()
34+
"systemmode"
2435
} else {
25-
env::var("EMULATION_MODE").unwrap_or_else(|_| {
26-
println!(
27-
"cargo:warning=No emulation mode feature enabled or EMULATION_MODE env specified for libafl_qemu, supported: usermode, systemmmode - defaulting to usermode"
28-
);
29-
"usermode".to_string()
30-
})
36+
unreachable!(
37+
"The above macros, `assert_unique_feature` and `assert_at_least_one_feature`, should \
38+
panic before this code is reached."
39+
);
3140
};
32-
println!("cargo::rustc-check-cfg=cfg(emulation_mode, values(\"usermode\", \"systemmode\"))");
33-
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
34-
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
3541

3642
// Make sure we have at most one architecutre feature set
3743
// Else, we default to `x86_64` - having a default makes CI easier :)
@@ -100,7 +106,7 @@ pub fn build() {
100106
// If the bindings are built and differ from the current stub, replace it with the freshly generated bindings
101107
maybe_generate_stub_bindings(
102108
&cpu_target,
103-
&emulation_mode,
109+
emulation_mode,
104110
stub_bindings_file.as_path(),
105111
bindings_file.as_path(),
106112
);

libafl_qemu/libafl_qemu_sys/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ use strum_macros::EnumIter;
1717
mod bindings;
1818
pub use bindings::*;
1919

20-
#[cfg(emulation_mode = "usermode")]
20+
#[cfg(feature = "usermode")]
2121
mod usermode;
22-
#[cfg(emulation_mode = "usermode")]
22+
#[cfg(feature = "usermode")]
2323
pub use usermode::*;
2424

25-
// #[cfg(emulation_mode = "systemmode")]
25+
// #[cfg(feature = "systemmode")]
2626
// mod systemmode;
27-
// #[cfg(emulation_mode = "systemmode")]
27+
// #[cfg(feature = "systemmode")]
2828
// pub use systemmode::*;
2929

3030
/// Safe linking with of extern "C" functions.

libafl_qemu/libafl_qemu_sys/src/usermode.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ impl IntoPy<PyObject> for MmapPerms {
104104
n.into_py(py)
105105
}
106106
}
107+
108+
#[cfg(target_os = "linux")]
107109
impl From<libafl_mapinfo> for MapInfo {
108110
fn from(map_info: libafl_mapinfo) -> Self {
109111
let path: Option<String> = if map_info.path.is_null() {

libafl_qemu/src/command/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use libafl::{
1212
};
1313
use libafl_bolts::AsSlice;
1414
use libafl_qemu_sys::GuestAddr;
15-
#[cfg(emulation_mode = "systemmode")]
15+
#[cfg(feature = "systemmode")]
1616
use libafl_qemu_sys::GuestPhysAddr;
1717
use libc::c_uint;
1818
use num_enum::TryFromPrimitive;
@@ -457,7 +457,7 @@ where
457457
}
458458

459459
// Auto page filtering if option is enabled
460-
#[cfg(emulation_mode = "systemmode")]
460+
#[cfg(feature = "systemmode")]
461461
if emu.driver_mut().allow_page_on_start() {
462462
if let Some(page_id) = qemu.current_cpu().unwrap().current_paging_id() {
463463
emu.modules_mut().modules_mut().allow_page_id_all(page_id);
@@ -566,13 +566,13 @@ where
566566
}
567567
}
568568

569-
#[cfg(emulation_mode = "systemmode")]
569+
#[cfg(feature = "systemmode")]
570570
#[derive(Debug, Clone)]
571571
pub struct PageAllowCommand {
572572
page_id: GuestPhysAddr,
573573
}
574574

575-
#[cfg(emulation_mode = "systemmode")]
575+
#[cfg(feature = "systemmode")]
576576
impl<CM, ED, ET, S, SM> IsCommand<CM, ED, ET, S, SM> for PageAllowCommand
577577
where
578578
ET: EmulatorModuleTuple<S>,
@@ -760,7 +760,7 @@ impl Display for AddressAllowCommand {
760760
}
761761
}
762762

763-
#[cfg(emulation_mode = "systemmode")]
763+
#[cfg(feature = "systemmode")]
764764
impl Display for PageAllowCommand {
765765
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
766766
write!(f, "Allowed page: {:?}", self.page_id)

libafl_qemu/src/emu/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use libafl::{
66
};
77
use libafl_bolts::tuples::{tuple_list, Prepend};
88

9-
#[cfg(emulation_mode = "systemmode")]
9+
#[cfg(feature = "systemmode")]
1010
use crate::FastSnapshotManager;
1111
use crate::{
1212
command::{CommandManager, NopCommandManager, StdCommandManager},
@@ -53,7 +53,7 @@ where
5353
}
5454
}
5555

56-
#[cfg(emulation_mode = "usermode")]
56+
#[cfg(feature = "usermode")]
5757
impl<S> EmulatorBuilder<StdCommandManager<S>, StdEmulatorDriver, (), S, StdSnapshotManager>
5858
where
5959
S: State + HasExecutions + Unpin,
@@ -73,7 +73,7 @@ where
7373
}
7474
}
7575

76-
#[cfg(emulation_mode = "systemmode")]
76+
#[cfg(feature = "systemmode")]
7777
impl<S> EmulatorBuilder<StdCommandManager<S>, StdEmulatorDriver, (), S, StdSnapshotManager>
7878
where
7979
S: State + HasExecutions + Unpin,

libafl_qemu/src/emu/drivers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub struct StdEmulatorDriver {
117117
input_location: OnceCell<InputLocation>,
118118
#[builder(default = true)]
119119
hooks_locked: bool,
120-
#[cfg(emulation_mode = "systemmode")]
120+
#[cfg(feature = "systemmode")]
121121
#[builder(default = false)]
122122
allow_page_on_start: bool,
123123
#[cfg(feature = "x86_64")]
@@ -147,7 +147,7 @@ impl StdEmulatorDriver {
147147
was_locked
148148
}
149149

150-
#[cfg(emulation_mode = "systemmode")]
150+
#[cfg(feature = "systemmode")]
151151
pub fn allow_page_on_start(&self) -> bool {
152152
self.allow_page_on_start
153153
}

0 commit comments

Comments
 (0)