Skip to content

Commit 602bce4

Browse files
authored
Fix LLVMFuzzerCustomMutator with different sizes (#2347)
* Fix LLVMFuzzerCustomMutator with different sizes * removed needles extra thingy * clippy * more clip
1 parent 50d7542 commit 602bce4

File tree

2 files changed

+30
-22
lines changed

2 files changed

+30
-22
lines changed

libafl_qemu/src/helpers/injections.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,8 @@ where
303303
} else {
304304
libs.iter()
305305
.filter_map(|lib| find_function(qemu, &lib.name, name, lib.off).unwrap())
306-
.map(|func_pc| {
307-
log::info!("Injections: Function {name} found at {func_pc:#x}",);
308-
func_pc
306+
.inspect(|&func_pc| {
307+
log::info!("Injections: Function {name} found at {func_pc:#x}");
309308
})
310309
.collect()
311310
};

libafl_targets/src/libfuzzer/mutators.rs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use libafl::{
1919
state::{HasCorpus, HasMaxSize, HasRand},
2020
Error,
2121
};
22-
use libafl_bolts::{rands::Rand, AsSlice, Named};
22+
use libafl_bolts::{rands::Rand, AsSlice, HasLen, Named};
2323

2424
extern "C" {
2525
fn libafl_targets_has_libfuzzer_custom_mutator() -> bool;
@@ -322,10 +322,9 @@ where
322322
input: &mut S::Input,
323323
) -> Result<MutationResult, Error> {
324324
let seed = state.rand_mut().next();
325-
let target = input.bytes();
326-
let mut bytes = Vec::with_capacity(state.max_size());
327-
bytes.extend_from_slice(target.as_slice());
328-
bytes.resize(state.max_size(), 0);
325+
let len_orig = input.bytes().len();
326+
let len_max = state.max_size();
327+
input.resize(len_max, 0);
329328

330329
// we assume that the fuzzer did not use this mutator, but instead utilised their own
331330
let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated)));
@@ -334,11 +333,11 @@ where
334333
let mut mutator = mutator.borrow_mut();
335334
mutator.replace(Box::new(proxy.weak()))
336335
});
337-
let new_size = unsafe {
336+
let new_len = unsafe {
338337
libafl_targets_libfuzzer_custom_mutator(
339-
bytes.as_mut_ptr(),
340-
target.as_slice().len(),
341-
bytes.len(),
338+
input.bytes_mut().as_mut_ptr(),
339+
len_orig,
340+
len_max,
342341
seed as u32,
343342
)
344343
};
@@ -350,15 +349,17 @@ where
350349
if result.deref().borrow().is_err() {
351350
return result.replace(Ok(MutationResult::Skipped));
352351
}
353-
bytes.truncate(new_size);
354-
input.bytes_mut().copy_from_slice(&bytes);
352+
if new_len > len_max {
353+
return Err(Error::illegal_state("LLVMFuzzerCustomMutator returned more bytes than allowed. Expected up to {max_len} but got {new_len}"));
354+
}
355+
input.resize(new_len, 0);
355356
Ok(MutationResult::Mutated)
356357
}
357358
}
358359

359360
impl<MT, SM> Named for LLVMCustomMutator<MT, SM, true> {
360361
fn name(&self) -> &Cow<'static, str> {
361-
static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomCrossover");
362+
static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator");
362363
&NAME
363364
}
364365
}
@@ -411,7 +412,11 @@ where
411412

412413
let seed = state.rand_mut().next();
413414
let mut out = vec![0u8; state.max_size()];
414-
let data1 = input.bytes();
415+
416+
let len_max = state.max_size();
417+
let len_orig = input.len();
418+
419+
input.resize(len_max, 0);
415420

416421
// we assume that the fuzzer did not use this mutator, but instead utilised their own
417422
let result = Rc::new(RefCell::new(Ok(MutationResult::Mutated)));
@@ -420,14 +425,14 @@ where
420425
let mut mutator = mutator.borrow_mut();
421426
mutator.replace(Box::new(proxy.weak()))
422427
});
423-
let new_size = unsafe {
428+
let new_len = unsafe {
424429
libafl_targets_libfuzzer_custom_crossover(
425-
data1.as_ptr(),
426-
data1.len(),
430+
input.bytes_mut().as_mut_ptr(),
431+
len_orig,
427432
data2.as_ptr(),
428433
data2.len(),
429434
out.as_mut_ptr(),
430-
out.len(),
435+
len_max,
431436
seed as u32,
432437
)
433438
};
@@ -439,8 +444,12 @@ where
439444
if result.deref().borrow().is_err() {
440445
return result.replace(Ok(MutationResult::Skipped));
441446
}
442-
out.truncate(new_size);
443-
input.bytes_mut().copy_from_slice(&out);
447+
448+
if new_len > len_max {
449+
return Err(Error::illegal_state("LLVMFuzzerCustomCrossOver returned more bytes than allowed. Expected up to {max_len} but got {new_len}"));
450+
}
451+
452+
input.resize(new_len, 0);
444453
Ok(MutationResult::Mutated)
445454
}
446455
}

0 commit comments

Comments
 (0)