From 602bce446f8087cc49cd56aa323bff9f3db14c0d Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 28 Jun 2024 16:40:41 +0200 Subject: [PATCH] Fix LLVMFuzzerCustomMutator with different sizes (#2347) * Fix LLVMFuzzerCustomMutator with different sizes * removed needles extra thingy * clippy * more clip --- libafl_qemu/src/helpers/injections.rs | 5 +-- libafl_targets/src/libfuzzer/mutators.rs | 47 ++++++++++++++---------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/libafl_qemu/src/helpers/injections.rs b/libafl_qemu/src/helpers/injections.rs index d5a0ca1130..68b73f2022 100644 --- a/libafl_qemu/src/helpers/injections.rs +++ b/libafl_qemu/src/helpers/injections.rs @@ -303,9 +303,8 @@ where } else { libs.iter() .filter_map(|lib| find_function(qemu, &lib.name, name, lib.off).unwrap()) - .map(|func_pc| { - log::info!("Injections: Function {name} found at {func_pc:#x}",); - func_pc + .inspect(|&func_pc| { + log::info!("Injections: Function {name} found at {func_pc:#x}"); }) .collect() }; diff --git a/libafl_targets/src/libfuzzer/mutators.rs b/libafl_targets/src/libfuzzer/mutators.rs index 0e8fee9848..71ec0193b0 100644 --- a/libafl_targets/src/libfuzzer/mutators.rs +++ b/libafl_targets/src/libfuzzer/mutators.rs @@ -19,7 +19,7 @@ use libafl::{ state::{HasCorpus, HasMaxSize, HasRand}, Error, }; -use libafl_bolts::{rands::Rand, AsSlice, Named}; +use libafl_bolts::{rands::Rand, AsSlice, HasLen, Named}; extern "C" { fn libafl_targets_has_libfuzzer_custom_mutator() -> bool; @@ -322,10 +322,9 @@ where input: &mut S::Input, ) -> Result { let seed = state.rand_mut().next(); - let target = input.bytes(); - let mut bytes = Vec::with_capacity(state.max_size()); - bytes.extend_from_slice(target.as_slice()); - bytes.resize(state.max_size(), 0); + let len_orig = input.bytes().len(); + let len_max = state.max_size(); + input.resize(len_max, 0); // we assume that the fuzzer did not use this mutator, but instead utilised their own let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated))); @@ -334,11 +333,11 @@ where let mut mutator = mutator.borrow_mut(); mutator.replace(Box::new(proxy.weak())) }); - let new_size = unsafe { + let new_len = unsafe { libafl_targets_libfuzzer_custom_mutator( - bytes.as_mut_ptr(), - target.as_slice().len(), - bytes.len(), + input.bytes_mut().as_mut_ptr(), + len_orig, + len_max, seed as u32, ) }; @@ -350,15 +349,17 @@ where if result.deref().borrow().is_err() { return result.replace(Ok(MutationResult::Skipped)); } - bytes.truncate(new_size); - input.bytes_mut().copy_from_slice(&bytes); + if new_len > len_max { + return Err(Error::illegal_state("LLVMFuzzerCustomMutator returned more bytes than allowed. Expected up to {max_len} but got {new_len}")); + } + input.resize(new_len, 0); Ok(MutationResult::Mutated) } } impl Named for LLVMCustomMutator { fn name(&self) -> &Cow<'static, str> { - static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomCrossover"); + static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator"); &NAME } } @@ -411,7 +412,11 @@ where let seed = state.rand_mut().next(); let mut out = vec![0u8; state.max_size()]; - let data1 = input.bytes(); + + let len_max = state.max_size(); + let len_orig = input.len(); + + input.resize(len_max, 0); // we assume that the fuzzer did not use this mutator, but instead utilised their own let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated))); @@ -420,14 +425,14 @@ where let mut mutator = mutator.borrow_mut(); mutator.replace(Box::new(proxy.weak())) }); - let new_size = unsafe { + let new_len = unsafe { libafl_targets_libfuzzer_custom_crossover( - data1.as_ptr(), - data1.len(), + input.bytes_mut().as_mut_ptr(), + len_orig, data2.as_ptr(), data2.len(), out.as_mut_ptr(), - out.len(), + len_max, seed as u32, ) }; @@ -439,8 +444,12 @@ where if result.deref().borrow().is_err() { return result.replace(Ok(MutationResult::Skipped)); } - out.truncate(new_size); - input.bytes_mut().copy_from_slice(&out); + + if new_len > len_max { + return Err(Error::illegal_state("LLVMFuzzerCustomCrossOver returned more bytes than allowed. Expected up to {max_len} but got {new_len}")); + } + + input.resize(new_len, 0); Ok(MutationResult::Mutated) } }