@@ -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
2424extern "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
359360impl < 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