@@ -19,7 +19,7 @@ use libafl::{
19
19
state:: { HasCorpus , HasMaxSize , HasRand } ,
20
20
Error ,
21
21
} ;
22
- use libafl_bolts:: { rands:: Rand , AsSlice , Named } ;
22
+ use libafl_bolts:: { rands:: Rand , AsSlice , HasLen , Named } ;
23
23
24
24
extern "C" {
25
25
fn libafl_targets_has_libfuzzer_custom_mutator ( ) -> bool ;
@@ -322,10 +322,9 @@ where
322
322
input : & mut S :: Input ,
323
323
) -> Result < MutationResult , Error > {
324
324
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 ) ;
329
328
330
329
// we assume that the fuzzer did not use this mutator, but instead utilised their own
331
330
let result = Rc :: new ( RefCell :: new ( Ok ( MutationResult :: Mutated ) ) ) ;
@@ -334,11 +333,11 @@ where
334
333
let mut mutator = mutator. borrow_mut ( ) ;
335
334
mutator. replace ( Box :: new ( proxy. weak ( ) ) )
336
335
} ) ;
337
- let new_size = unsafe {
336
+ let new_len = unsafe {
338
337
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 ,
342
341
seed as u32 ,
343
342
)
344
343
} ;
@@ -350,15 +349,17 @@ where
350
349
if result. deref ( ) . borrow ( ) . is_err ( ) {
351
350
return result. replace ( Ok ( MutationResult :: Skipped ) ) ;
352
351
}
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 ) ;
355
356
Ok ( MutationResult :: Mutated )
356
357
}
357
358
}
358
359
359
360
impl < MT , SM > Named for LLVMCustomMutator < MT , SM , true > {
360
361
fn name ( & self ) -> & Cow < ' static , str > {
361
- static NAME : Cow < ' static , str > = Cow :: Borrowed ( "LLVMCustomCrossover " ) ;
362
+ static NAME : Cow < ' static , str > = Cow :: Borrowed ( "LLVMCustomMutator " ) ;
362
363
& NAME
363
364
}
364
365
}
@@ -411,7 +412,11 @@ where
411
412
412
413
let seed = state. rand_mut ( ) . next ( ) ;
413
414
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 ) ;
415
420
416
421
// we assume that the fuzzer did not use this mutator, but instead utilised their own
417
422
let result = Rc :: new ( RefCell :: new ( Ok ( MutationResult :: Mutated ) ) ) ;
@@ -420,14 +425,14 @@ where
420
425
let mut mutator = mutator. borrow_mut ( ) ;
421
426
mutator. replace ( Box :: new ( proxy. weak ( ) ) )
422
427
} ) ;
423
- let new_size = unsafe {
428
+ let new_len = unsafe {
424
429
libafl_targets_libfuzzer_custom_crossover (
425
- data1 . as_ptr ( ) ,
426
- data1 . len ( ) ,
430
+ input . bytes_mut ( ) . as_mut_ptr ( ) ,
431
+ len_orig ,
427
432
data2. as_ptr ( ) ,
428
433
data2. len ( ) ,
429
434
out. as_mut_ptr ( ) ,
430
- out . len ( ) ,
435
+ len_max ,
431
436
seed as u32 ,
432
437
)
433
438
} ;
@@ -439,8 +444,12 @@ where
439
444
if result. deref ( ) . borrow ( ) . is_err ( ) {
440
445
return result. replace ( Ok ( MutationResult :: Skipped ) ) ;
441
446
}
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 ) ;
444
453
Ok ( MutationResult :: Mutated )
445
454
}
446
455
}
0 commit comments