Skip to content

Commit cf23695

Browse files
domenukkandreafioraldi
authored andcommitted
Fix misaligned ptr accesses and other clippy issues (#94)
* more docs * more docs: * more docu * more docu * finished docs * cleaned up markup * must_use tags added * more docs * swapped if/else, as per clippy * more docu, less clippy * more fixes * removed misaligned ptrs * fixed testcases * fixed arith mutators
1 parent 7f06e36 commit cf23695

File tree

1 file changed

+63
-56
lines changed

1 file changed

+63
-56
lines changed

libafl/src/mutators/mutations.rs

Lines changed: 63 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use crate::{
1313
use alloc::{borrow::ToOwned, vec::Vec};
1414
use core::{
1515
cmp::{max, min},
16+
convert::TryInto,
1617
marker::PhantomData,
18+
mem::size_of,
1719
};
1820

1921
/// Mem move in the own vec
@@ -53,6 +55,7 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
5355
}
5456
}
5557

58+
/// The max value that will be added or subtracted during add mutations
5659
const ARITH_MAX: u64 = 35;
5760

5861
const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127];
@@ -531,6 +534,7 @@ where
531534
}
532535

533536
/// Word add mutation for inputs with a bytes vector
537+
/// adds or subtracts a random value up to [`ARITH_MAX`] to a [`u16`] at a random place in the [`Vec`].
534538
#[derive(Default)]
535539
pub struct WordAddMutator<I, R, S>
536540
where
@@ -553,21 +557,23 @@ where
553557
input: &mut I,
554558
_stage_idx: i32,
555559
) -> Result<MutationResult, Error> {
556-
if input.bytes().len() < 2 {
560+
if input.bytes().len() < size_of::<u16>() {
557561
Ok(MutationResult::Skipped)
558562
} else {
559-
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
560-
unsafe {
561-
// Moar speed, no bounds checks
562-
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
563-
let num = 1 + state.rand_mut().below(ARITH_MAX) as u16;
564-
match state.rand_mut().below(4) {
565-
0 => *ptr = (*ptr).wrapping_add(num),
566-
1 => *ptr = (*ptr).wrapping_sub(num),
567-
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
568-
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
569-
};
563+
let bytes = input.bytes_mut();
564+
let idx = state
565+
.rand_mut()
566+
.below((bytes.len() - size_of::<u16>() + 1) as u64) as usize;
567+
let val = u16::from_ne_bytes(bytes[idx..idx + size_of::<u16>()].try_into().unwrap());
568+
let num = 1 + state.rand_mut().below(ARITH_MAX) as u16;
569+
let new_bytes = match state.rand_mut().below(4) {
570+
0 => val.wrapping_add(num),
571+
1 => val.wrapping_sub(num),
572+
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
573+
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
570574
}
575+
.to_ne_bytes();
576+
bytes[idx..idx + size_of::<u16>()].copy_from_slice(&new_bytes);
571577
Ok(MutationResult::Mutated)
572578
}
573579
}
@@ -599,7 +605,8 @@ where
599605
}
600606
}
601607

602-
/// Dword add mutation for inputs with a bytes vector
608+
/// Dword add mutation for inputs with a bytes vector.
609+
/// Adds a random value up to `ARITH_MAX` to a [`u32`] at a random place in the [`Vec`], in random byte order.
603610
#[derive(Default)]
604611
pub struct DwordAddMutator<I, R, S>
605612
where
@@ -622,21 +629,23 @@ where
622629
input: &mut I,
623630
_stage_idx: i32,
624631
) -> Result<MutationResult, Error> {
625-
if input.bytes().len() < 4 {
632+
if input.bytes().len() < size_of::<u32>() {
626633
Ok(MutationResult::Skipped)
627634
} else {
628-
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
629-
unsafe {
630-
// Moar speed, no bound check
631-
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
632-
let num = 1 + state.rand_mut().below(ARITH_MAX) as u32;
633-
match state.rand_mut().below(4) {
634-
0 => *ptr = (*ptr).wrapping_add(num),
635-
1 => *ptr = (*ptr).wrapping_sub(num),
636-
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
637-
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
638-
};
635+
let bytes = input.bytes_mut();
636+
let idx = state
637+
.rand_mut()
638+
.below((bytes.len() - size_of::<u32>() + 1) as u64) as usize;
639+
let val = u32::from_ne_bytes(bytes[idx..idx + size_of::<u32>()].try_into().unwrap());
640+
let num = 1 + state.rand_mut().below(ARITH_MAX) as u32;
641+
let new_bytes = match state.rand_mut().below(4) {
642+
0 => val.wrapping_add(num),
643+
1 => val.wrapping_sub(num),
644+
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
645+
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
639646
}
647+
.to_ne_bytes();
648+
bytes[idx..idx + size_of::<u32>()].copy_from_slice(&new_bytes);
640649
Ok(MutationResult::Mutated)
641650
}
642651
}
@@ -694,18 +703,20 @@ where
694703
if input.bytes().len() < 8 {
695704
Ok(MutationResult::Skipped)
696705
} else {
697-
let idx = state.rand_mut().below(input.bytes().len() as u64 - 7) as usize;
698-
unsafe {
699-
// Moar speed, no bounds checks
700-
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u64;
701-
let num = 1 + state.rand_mut().below(ARITH_MAX) as u64;
702-
match state.rand_mut().below(4) {
703-
0 => *ptr = (*ptr).wrapping_add(num),
704-
1 => *ptr = (*ptr).wrapping_sub(num),
705-
2 => *ptr = ((*ptr).swap_bytes().wrapping_add(num)).swap_bytes(),
706-
_ => *ptr = ((*ptr).swap_bytes().wrapping_sub(num)).swap_bytes(),
707-
};
706+
let bytes = input.bytes_mut();
707+
let idx = state
708+
.rand_mut()
709+
.below((bytes.len() - size_of::<u64>() + 1) as u64) as usize;
710+
let val = u64::from_ne_bytes(bytes[idx..idx + size_of::<u64>()].try_into().unwrap());
711+
let num = 1 + state.rand_mut().below(ARITH_MAX) as u64;
712+
let new_bytes = match state.rand_mut().below(4) {
713+
0 => val.wrapping_add(num),
714+
1 => val.wrapping_sub(num),
715+
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
716+
_ => val.swap_bytes().wrapping_sub(num).swap_bytes(),
708717
}
718+
.to_ne_bytes();
719+
bytes[idx..idx + size_of::<u64>()].copy_from_slice(&new_bytes);
709720
Ok(MutationResult::Mutated)
710721
}
711722
}
@@ -829,18 +840,16 @@ where
829840
if input.bytes().len() < 2 {
830841
Ok(MutationResult::Skipped)
831842
} else {
832-
let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize;
843+
let bytes = input.bytes_mut();
844+
let idx = state.rand_mut().below(bytes.len() as u64 - 1) as usize;
833845
let val =
834846
INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;
835-
unsafe {
836-
// Moar speed, no bounds checks
837-
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16;
838-
if state.rand_mut().below(2) == 0 {
839-
*ptr = val;
840-
} else {
841-
*ptr = val.swap_bytes();
842-
}
843-
}
847+
let new_bytes = if state.rand_mut().below(2) == 0 {
848+
val.to_be_bytes()
849+
} else {
850+
val.to_le_bytes()
851+
};
852+
bytes[idx..idx + size_of::<u16>()].copy_from_slice(&new_bytes);
844853
Ok(MutationResult::Mutated)
845854
}
846855
}
@@ -899,18 +908,16 @@ where
899908
if input.bytes().len() < 4 {
900909
Ok(MutationResult::Skipped)
901910
} else {
902-
let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize;
911+
let bytes = input.bytes_mut();
912+
let idx = state.rand_mut().below(bytes.len() as u64 - 3) as usize;
903913
let val =
904914
INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;
905-
unsafe {
906-
// Moar speed, no bounds checks
907-
let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32;
908-
if state.rand_mut().below(2) == 0 {
909-
*ptr = val;
910-
} else {
911-
*ptr = val.swap_bytes();
912-
}
913-
}
915+
let new_bytes = if state.rand_mut().below(2) == 0 {
916+
val.to_be_bytes()
917+
} else {
918+
val.to_le_bytes()
919+
};
920+
bytes[idx..idx + new_bytes.len()].copy_from_slice(&new_bytes);
914921
Ok(MutationResult::Mutated)
915922
}
916923
}

0 commit comments

Comments
 (0)