Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcondiro committed Jan 22, 2025
2 parents ee7172d + e844290 commit a85bedc
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ jobs:
- 'libafl_bolts/**'
- 'libafl_targets/**'
- 'libafl_qemu/**'
- 'fuzzers/*qemu*/**'
- 'fuzzers/**/*qemu*/**'
fuzzers-qemu:
needs:
Expand Down
34 changes: 33 additions & 1 deletion fuzzers/binary_only/qemu_coverage/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,38 @@ rm -rf ${CARGO_MAKE_CRATE_TARGET_DIRECTORY}
cargo clean
'''

[tasks.test_inner]
script_runner = "@shell"
script = '''
cargo make ${FEATURE} || exit 1
cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_merge -- \
-i ${TARGET_DIR}/drcov-000.log ${TARGET_DIR}/drcov-001.log ${TARGET_DIR}/drcov-002.log ${TARGET_DIR}/drcov-003.log \
--output ${TARGET_DIR}/drcov-merged.log || exit 1
TMP=$(cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_dump_addrs -- \
-i ${TARGET_DIR}/drcov-merged.log | wc -l || exit 1)
NB_BLOCKS=$((TMP - 1))
echo "Nb blocks found: $NB_BLOCKS"
if [ $NB_BLOCKS -ge 1700 ]; then
echo "Test succeeded"
else
echo "Did not find more than 1700 blocks."
exit 1
fi
'''

[tasks.arm]
command = "cargo"
args = ["make", "-p", "arm", "run"]

[tasks.test_arm]
command = "cargo"
args = ["make", "-p", "arm", "test_inner"]

[tasks.aarch64]
command = "cargo"
args = ["make", "-p", "aarch64", "run"]
Expand All @@ -300,6 +328,10 @@ args = ["make", "-p", "aarch64", "run"]
command = "cargo"
args = ["make", "-p", "x86_64", "run"]

[tasks.test_x86_64]
command = "cargo"
args = ["make", "-p", "x86_64", "test_inner"]

[tasks.i386]
command = "cargo"
args = ["make", "-p", "i386", "run"]
Expand All @@ -316,4 +348,4 @@ args = ["make", "-p", "ppc", "run"]
dependencies = ["arm", "aarch64", "x86_64", "i386", "mips", "ppc"]

[tasks.lightweight]
dependencies = ["arm", "x86_64"]
dependencies = ["test_x86_64", "test_arm"]
2 changes: 1 addition & 1 deletion fuzzers/binary_only/qemu_coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This folder contains an example fuzzer which runs each entry in the input corpus and collects
the cumuative coverage data in drcov format. This fuzzer also distributes the test cases in
the input corupus evenly across the selected cores.
the input corpus evenly across the selected cores.

The following architectures are supported:
* arm
Expand Down
30 changes: 16 additions & 14 deletions fuzzers/binary_only/qemu_coverage/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ use libafl_bolts::{
AsSlice,
};
use libafl_qemu::{
elf::EasyElf,
modules::{drcov::DrCovModule, utils::filters::StdAddressFilter},
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, QemuExecutor,
QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
elf::EasyElf, modules::drcov::DrCovModule, ArchExtras, CallingConvention, Emulator, GuestAddr,
GuestReg, MmapPerms, Qemu, QemuExecutor, QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
};

#[derive(Default)]
Expand Down Expand Up @@ -127,9 +125,14 @@ pub fn fuzz() {
mut mgr: LlmpRestartingEventManager<_, _, _, _, _>,
client_description: ClientDescription| {
let mut cov_path = options.coverage_path.clone();
let core_id = client_description.core_id();

let coverage_name = cov_path.file_stem().unwrap().to_str().unwrap();
let coverage_extension = cov_path.extension().unwrap_or_default().to_str().unwrap();
let core = core_id.0;
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));

let emulator_modules = tuple_list!(DrCovModule::builder()
.filter(StdAddressFilter::default())
.filename(cov_path.clone())
.full_trace(false)
.build());
Expand Down Expand Up @@ -175,9 +178,9 @@ pub fn fuzz() {

let stack_ptr: GuestAddr = qemu.read_reg(Regs::Sp).unwrap();

let reset = |buf: &[u8], len: GuestReg| -> Result<(), QemuRWError> {
let reset = |qemu: Qemu, buf: &[u8], len: GuestReg| -> Result<(), QemuRWError> {
unsafe {
let _ = qemu.write_mem(input_addr, buf);
qemu.write_mem(input_addr, buf)?;
qemu.write_reg(Regs::Pc, test_one_input_ptr)?;
qemu.write_reg(Regs::Sp, stack_ptr)?;
qemu.write_return_address(ret_addr)?;
Expand All @@ -197,7 +200,9 @@ pub fn fuzz() {
};

let mut harness =
|_emulator: &mut Emulator<_, _, _, _, _, _, _>, _state: &mut _, input: &BytesInput| {
|emulator: &mut Emulator<_, _, _, _, _, _, _>, state: &mut _, input: &BytesInput| {
let qemu = emulator.qemu();

let target = input.target_bytes();
let mut buf = target.as_slice();
let mut len = buf.len();
Expand All @@ -206,7 +211,8 @@ pub fn fuzz() {
len = MAX_INPUT_SIZE;
}
let len = len as GuestReg;
reset(buf, len).unwrap();
reset(qemu, buf, len).unwrap();

ExitKind::Ok
};

Expand All @@ -215,6 +221,7 @@ pub fn fuzz() {
.cores
.position(core_id)
.expect("Failed to get core index");

let files = corpus_files
.iter()
.skip(files_per_core * core_idx)
Expand Down Expand Up @@ -245,11 +252,6 @@ pub fn fuzz() {
let scheduler = QueueScheduler::new();
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

let coverage_name = cov_path.file_stem().unwrap().to_str().unwrap();
let coverage_extension = cov_path.extension().unwrap_or_default().to_str().unwrap();
let core = core_id.0;
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));

let mut executor = QemuExecutor::new(
emulator,
&mut harness,
Expand Down
2 changes: 1 addition & 1 deletion libafl_qemu/src/modules/cmplog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ where
return None;
}
}
let state = state.expect("The gen_unique_cmp_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_cmp_ids hook works only for in-process fuzzing. Is the Executor initialized?");
if state.metadata_map().get::<QemuCmpsMapMetadata>().is_none() {
state.add_metadata(QemuCmpsMapMetadata::new());
}
Expand Down
17 changes: 9 additions & 8 deletions libafl_qemu/src/modules/drcov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,26 +265,27 @@ where
I: Unpin,
S: Unpin + HasMetadata,
{
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>)
where
ET: EmulatorModuleTuple<I, S>,
{
emulator_modules.blocks(
Hook::Function(gen_unique_block_ids::<ET, F, I, S>),
Hook::Function(gen_block_lengths::<ET, F, I, S>),
Hook::Function(exec_trace_block::<ET, F, I, S>),
);
}

#[cfg(feature = "usermode")]
fn first_exec<ET>(
&mut self,
qemu: Qemu,
_emulator_modules: &mut EmulatorModules<ET, I, S>,
emulator_modules: &mut EmulatorModules<ET, I, S>,
_state: &mut S,
) where
ET: EmulatorModuleTuple<I, S>,
{
emulator_modules.blocks(
Hook::Function(gen_unique_block_ids::<ET, F, I, S>),
Hook::Function(gen_block_lengths::<ET, F, I, S>),
Hook::Function(exec_trace_block::<ET, F, I, S>),
);

if self.module_mapping.is_none() {
log::info!("Auto-filling module mapping for DrCov module from QEMU mapping.");

Expand Down Expand Up @@ -392,7 +393,7 @@ where
return None;
}

let state = state.expect("The gen_unique_block_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_block_ids hook works only for in-process fuzzing. Is the Executor initialized?");
if state
.metadata_map_mut()
.get_mut::<DrCovMetadata>()
Expand Down
2 changes: 1 addition & 1 deletion libafl_qemu/src/modules/edges/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ mod generators {

let mask: usize = get_mask::<IS_CONST_MAP, MAP_SIZE>();

let state = state.expect("The gen_unique_edge_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_edge_ids hook works only for in-process fuzzing. Is the Executor initialized?");
let meta = state.metadata_or_insert_with(QemuEdgesMapMetadata::new);

match meta.map.entry((src, dest)) {
Expand Down

0 comments on commit a85bedc

Please sign in to comment.