Use nonzero! macro (#2589)
* nonzero_lit * nonzero * std instead of core * a * l * test * import * api * api * aaaaa * apiapi * api * api * api * mm * api * non zero * FMT * pls * nnnaaasdfadsfafdsa * pls * MM * fix * a * sat add * aa * mistake * unreachable * no generic * api change * a
This commit is contained in:
parent
3b31b4d796
commit
fda1596ee2
@ -3,7 +3,6 @@ extern crate libafl;
|
|||||||
extern crate libafl_bolts;
|
extern crate libafl_bolts;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{InMemoryCorpus, OnDiskCorpus},
|
corpus::{InMemoryCorpus, OnDiskCorpus},
|
||||||
events::SimpleEventManager,
|
events::SimpleEventManager,
|
||||||
@ -15,7 +14,7 @@ use libafl::{
|
|||||||
schedulers::QueueScheduler,
|
schedulers::QueueScheduler,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
|
||||||
/* ANCHOR_END: use */
|
/* ANCHOR_END: use */
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -77,7 +76,7 @@ fn main() {
|
|||||||
|
|
||||||
/* ANCHOR: generator */
|
/* ANCHOR: generator */
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -15,7 +15,7 @@ use libafl::{
|
|||||||
schedulers::QueueScheduler,
|
schedulers::QueueScheduler,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
/* ANCHOR_END: use */
|
/* ANCHOR_END: use */
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ fn main() {
|
|||||||
/* ANCHOR_END: executor_with_observer */
|
/* ANCHOR_END: executor_with_observer */
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* ANCHOR: use */
|
/* ANCHOR: use */
|
||||||
extern crate libafl;
|
extern crate libafl;
|
||||||
extern crate libafl_bolts;
|
extern crate libafl_bolts;
|
||||||
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
corpus::{InMemoryCorpus, OnDiskCorpus},
|
corpus::{InMemoryCorpus, OnDiskCorpus},
|
||||||
@ -17,7 +18,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice, nonzero};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
/* ANCHOR_END: use */
|
/* ANCHOR_END: use */
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -20,7 +20,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
|
|
||||||
/// Coverage map with explicit assignments due to the lack of instrumentation
|
/// Coverage map with explicit assignments due to the lack of instrumentation
|
||||||
static mut SIGNALS: [u8; 16] = [0; 16];
|
static mut SIGNALS: [u8; 16] = [0; 16];
|
||||||
@ -116,7 +116,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -86,7 +86,7 @@ pub fn main() -> Result<(), Error> {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -23,7 +23,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::{HasSolutions, StdState},
|
state::{HasSolutions, StdState},
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
use libafl_targets::{edges_max_num, DifferentialAFLMapSwapObserver};
|
use libafl_targets::{edges_max_num, DifferentialAFLMapSwapObserver};
|
||||||
#[cfg(not(miri))]
|
#[cfg(not(miri))]
|
||||||
use mimalloc::MiMalloc;
|
use mimalloc::MiMalloc;
|
||||||
@ -247,7 +247,7 @@ pub fn main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -17,6 +17,7 @@ use libafl::{
|
|||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
ownedref::OwnedRefMut,
|
ownedref::OwnedRefMut,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
@ -103,7 +104,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -16,7 +16,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
use libc::c_uchar;
|
use libc::c_uchar;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -25,6 +25,7 @@ use libafl::{
|
|||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider},
|
shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
@ -112,7 +113,7 @@ pub fn main() {
|
|||||||
let mut executor = MyExecutor { shmem_id }.into_executor(tuple_list!(observer, bt_observer));
|
let mut executor = MyExecutor { shmem_id }.into_executor(tuple_list!(observer, bt_observer));
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -21,6 +21,7 @@ use libafl_bolts::shmem::StdShMemProvider;
|
|||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use libafl_bolts::shmem::UnixShMemProvider;
|
use libafl_bolts::shmem::UnixShMemProvider;
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider},
|
shmem::{ShMem, ShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
@ -97,7 +98,7 @@ pub fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(3).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -19,6 +19,7 @@ use libafl::{
|
|||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
ownedref::OwnedRefMut,
|
ownedref::OwnedRefMut,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{unix_shmem, ShMem, ShMemProvider},
|
shmem::{unix_shmem, ShMem, ShMemProvider},
|
||||||
@ -122,7 +123,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -18,7 +18,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
|
|
||||||
/// Coverage map with explicit assignments due to the lack of instrumentation
|
/// Coverage map with explicit assignments due to the lack of instrumentation
|
||||||
static mut SIGNALS: [u8; 16] = [0; 16];
|
static mut SIGNALS: [u8; 16] = [0; 16];
|
||||||
@ -113,7 +113,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -18,6 +18,7 @@ use libafl::{
|
|||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{unix_shmem, ShMemProvider},
|
shmem::{unix_shmem, ShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
@ -115,7 +116,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -206,8 +206,7 @@ pub fn main() {
|
|||||||
|
|
||||||
// Setup a mutational stage with a basic bytes mutator
|
// Setup a mutational stage with a basic bytes mutator
|
||||||
let mutator =
|
let mutator =
|
||||||
StdScheduledMutator::with_max_stack_pow(havoc_mutations().merge(tokens_mutations()), 6)
|
StdScheduledMutator::with_max_stack_pow(havoc_mutations().merge(tokens_mutations()), 6);
|
||||||
.unwrap();
|
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
fuzzer
|
fuzzer
|
||||||
|
@ -202,8 +202,7 @@ pub fn main() {
|
|||||||
|
|
||||||
// Setup a mutational stage with a basic bytes mutator
|
// Setup a mutational stage with a basic bytes mutator
|
||||||
let mutator =
|
let mutator =
|
||||||
StdScheduledMutator::with_max_stack_pow(havoc_mutations().merge(tokens_mutations()), 6)
|
StdScheduledMutator::with_max_stack_pow(havoc_mutations().merge(tokens_mutations()), 6);
|
||||||
.unwrap();
|
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
fuzzer
|
fuzzer
|
||||||
|
@ -15,7 +15,9 @@ use libafl::{
|
|||||||
state::{HasSolutions, StdState},
|
state::{HasSolutions, StdState},
|
||||||
Fuzzer, StdFuzzer,
|
Fuzzer, StdFuzzer,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, serdeany::RegistryBuilder, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{
|
||||||
|
nonzero, rands::StdRand, serdeany::RegistryBuilder, tuples::tuple_list, AsSlice,
|
||||||
|
};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use web_sys::{Performance, Window};
|
use web_sys::{Performance, Window};
|
||||||
|
|
||||||
@ -126,7 +128,7 @@ pub fn fuzz() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -25,7 +25,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
#[cfg(any(windows, unix))]
|
#[cfg(any(windows, unix))]
|
||||||
use libc::{abort, printf};
|
use libc::{abort, printf};
|
||||||
use static_alloc::Bump;
|
use static_alloc::Bump;
|
||||||
@ -144,7 +144,7 @@ pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -34,6 +34,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::Cores,
|
core_affinity::Cores,
|
||||||
|
nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
@ -240,7 +241,7 @@ pub extern "C" fn LLVMFuzzerRunDriver(
|
|||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
if input_dirs.is_empty() {
|
if input_dirs.is_empty() {
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandBytesGenerator::new(32).unwrap();
|
let mut generator = RandBytesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -18,7 +18,7 @@ use libafl::{
|
|||||||
stages::mutational::StdMutationalStage,
|
stages::mutational::StdMutationalStage,
|
||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice};
|
use libafl_bolts::{current_nanos, nonzero, rands::StdRand, tuples::tuple_list, AsSlice};
|
||||||
|
|
||||||
/// Coverage map with explicit assignments due to the lack of instrumentation
|
/// Coverage map with explicit assignments due to the lack of instrumentation
|
||||||
static mut SIGNALS: [u8; 16] = [0; 16];
|
static mut SIGNALS: [u8; 16] = [0; 16];
|
||||||
@ -93,7 +93,7 @@ fn input_generator() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandPrintablesGenerator::new(32).unwrap();
|
let mut generator = RandPrintablesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -602,8 +602,8 @@ fn fuzz_text(
|
|||||||
GrimoireRandomDeleteMutator::new(),
|
GrimoireRandomDeleteMutator::new(),
|
||||||
),
|
),
|
||||||
3,
|
3,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
let grimoire = StdMutationalStage::transforming(grimoire_mutator);
|
let grimoire = StdMutationalStage::transforming(grimoire_mutator);
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use core::num::NonZeroUsize;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
hash::{DefaultHasher, Hash, Hasher},
|
hash::{DefaultHasher, Hash, Hasher},
|
||||||
@ -59,20 +60,20 @@ impl CustomInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A generator for [`CustomInput`] used in this example
|
/// A generator for [`CustomInput`] used in this example
|
||||||
pub struct CustomInputGenerator<S: HasRand> {
|
pub struct CustomInputGenerator {
|
||||||
pub bytes_generator: RandBytesGenerator<S>,
|
pub bytes_generator: RandBytesGenerator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: HasRand> CustomInputGenerator<S> {
|
impl CustomInputGenerator {
|
||||||
/// Creates a new [`CustomInputGenerator`]
|
/// Creates a new [`CustomInputGenerator`]
|
||||||
pub fn new(max_len: usize) -> Result<Self, Error> {
|
pub fn new(max_len: NonZeroUsize) -> Self {
|
||||||
Ok(Self {
|
Self {
|
||||||
bytes_generator: RandBytesGenerator::new(max_len)?,
|
bytes_generator: RandBytesGenerator::new(max_len),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Generator<CustomInput, S> for CustomInputGenerator<S>
|
impl<S> Generator<CustomInput, S> for CustomInputGenerator
|
||||||
where
|
where
|
||||||
S: HasRand,
|
S: HasRand,
|
||||||
{
|
{
|
||||||
@ -99,15 +100,12 @@ pub struct ToggleOptionalByteArrayMutator<G> {
|
|||||||
generator: G,
|
generator: G,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> ToggleOptionalByteArrayMutator<RandBytesGenerator<S>>
|
impl ToggleOptionalByteArrayMutator<RandBytesGenerator> {
|
||||||
where
|
|
||||||
S: HasRand,
|
|
||||||
{
|
|
||||||
/// Creates a new [`ToggleOptionalByteArrayMutator`]
|
/// Creates a new [`ToggleOptionalByteArrayMutator`]
|
||||||
pub fn new(length: usize) -> Result<Self, Error> {
|
pub fn new(length: NonZeroUsize) -> Self {
|
||||||
Ok(Self {
|
Self {
|
||||||
generator: RandBytesGenerator::new(length)?,
|
generator: RandBytesGenerator::new(length),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ use libafl::{
|
|||||||
state::StdState,
|
state::StdState,
|
||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
current_nanos,
|
current_nanos, nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
tuples::{tuple_list, Merge, Prepend},
|
tuples::{tuple_list, Merge, Prepend},
|
||||||
};
|
};
|
||||||
@ -42,7 +42,7 @@ use {
|
|||||||
/// Coverage map with explicit assignments due to the lack of instrumentation
|
/// Coverage map with explicit assignments due to the lack of instrumentation
|
||||||
const SIGNALS_LEN: usize = 16;
|
const SIGNALS_LEN: usize = 16;
|
||||||
static mut SIGNALS: [u8; SIGNALS_LEN] = [0; 16];
|
static mut SIGNALS: [u8; SIGNALS_LEN] = [0; 16];
|
||||||
static mut SIGNALS_PTR: *mut u8 = unsafe { addr_of_mut!(SIGNALS) as _ };
|
static mut SIGNALS_PTR: *mut u8 = addr_of_mut!(SIGNALS) as _;
|
||||||
|
|
||||||
/// Assign a signal to the signals map
|
/// Assign a signal to the signals map
|
||||||
fn signals_set(idx: usize) {
|
fn signals_set(idx: usize) {
|
||||||
@ -131,8 +131,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator =
|
let mut generator = CustomInputGenerator::new(nonzero!(1));
|
||||||
CustomInputGenerator::new(1).expect("Failed to create our custom input generator");
|
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
@ -183,9 +182,7 @@ pub fn main() {
|
|||||||
// Then, mutators for the optional byte array, these return MutationResult::Skipped if the part is not present
|
// Then, mutators for the optional byte array, these return MutationResult::Skipped if the part is not present
|
||||||
.merge(optional_mapped_mutators)
|
.merge(optional_mapped_mutators)
|
||||||
// A custom mutator that sets the optional byte array to None if present, and generates a random byte array of length 1 if it is not
|
// A custom mutator that sets the optional byte array to None if present, and generates a random byte array of length 1 if it is not
|
||||||
.prepend(
|
.prepend(ToggleOptionalByteArrayMutator::new(nonzero!(1)))
|
||||||
ToggleOptionalByteArrayMutator::new(1).expect("Failed to create bytearray mutator"),
|
|
||||||
)
|
|
||||||
// Finally, a custom mutator that toggles the boolean part of the input
|
// Finally, a custom mutator that toggles the boolean part of the input
|
||||||
.prepend(ToggleBooleanMutator);
|
.prepend(ToggleBooleanMutator);
|
||||||
|
|
||||||
|
@ -156,8 +156,7 @@ pub fn main() {
|
|||||||
GramatronRecursionMutator::new()
|
GramatronRecursionMutator::new()
|
||||||
),
|
),
|
||||||
2,
|
2,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
fuzzer
|
fuzzer
|
||||||
|
@ -139,7 +139,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Setup a mutational stage with a basic bytes mutator
|
// Setup a mutational stage with a basic bytes mutator
|
||||||
let mutator = StdScheduledMutator::with_max_stack_pow(havoc_mutations(), 2).unwrap();
|
let mutator = StdScheduledMutator::with_max_stack_pow(havoc_mutations(), 2);
|
||||||
let grimoire_mutator = StdScheduledMutator::with_max_stack_pow(
|
let grimoire_mutator = StdScheduledMutator::with_max_stack_pow(
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
GrimoireExtensionMutator::new(),
|
GrimoireExtensionMutator::new(),
|
||||||
@ -150,8 +150,7 @@ pub fn main() {
|
|||||||
GrimoireRandomDeleteMutator::new(),
|
GrimoireRandomDeleteMutator::new(),
|
||||||
),
|
),
|
||||||
3,
|
3,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
let mut stages = tuple_list!(
|
let mut stages = tuple_list!(
|
||||||
generalization,
|
generalization,
|
||||||
StdMutationalStage::new(mutator),
|
StdMutationalStage::new(mutator),
|
||||||
|
@ -158,8 +158,7 @@ pub fn main() {
|
|||||||
NautilusSpliceMutator::new(&context),
|
NautilusSpliceMutator::new(&context),
|
||||||
),
|
),
|
||||||
2,
|
2,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
fuzzer
|
fuzzer
|
||||||
|
@ -116,7 +116,7 @@ pub fn main() {
|
|||||||
.expect("Failed to create the Executor");
|
.expect("Failed to create the Executor");
|
||||||
|
|
||||||
// Setup a mutational stage with a basic bytes mutator
|
// Setup a mutational stage with a basic bytes mutator
|
||||||
let mutator = StdScheduledMutator::with_max_stack_pow(encoded_mutations(), 2).unwrap();
|
let mutator = StdScheduledMutator::with_max_stack_pow(encoded_mutations(), 2);
|
||||||
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
|
||||||
println!("Decoder {:?} ...", &encoder_decoder);
|
println!("Decoder {:?} ...", &encoder_decoder);
|
||||||
|
@ -230,8 +230,7 @@ pub extern "C" fn libafl_main() {
|
|||||||
NautilusSpliceMutator::new(&context),
|
NautilusSpliceMutator::new(&context),
|
||||||
),
|
),
|
||||||
2,
|
2,
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if let Some(conv) = event_converter.take() {
|
if let Some(conv) = event_converter.take() {
|
||||||
let mut stages = tuple_list!(
|
let mut stages = tuple_list!(
|
||||||
|
@ -2,7 +2,10 @@ use alloc::{borrow::ToOwned, string::String, vec::Vec};
|
|||||||
use core::num::NonZero;
|
use core::num::NonZero;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::rands::{Rand, RomuDuoJrRand};
|
use libafl_bolts::{
|
||||||
|
nonzero,
|
||||||
|
rands::{Rand, RomuDuoJrRand},
|
||||||
|
};
|
||||||
use pyo3::prelude::PyObject;
|
use pyo3::prelude::PyObject;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -265,7 +268,7 @@ impl Context {
|
|||||||
.take_while(move |r| self.rules_to_min_size[*r] <= max_len)
|
.take_while(move |r| self.rules_to_min_size[*r] <= max_len)
|
||||||
.filter(move |r| {
|
.filter(move |r| {
|
||||||
self.rules_to_num_options[*r] > 1
|
self.rules_to_num_options[*r] > 1
|
||||||
|| rand.below(NonZero::new(100).unwrap()) <= p_include_short_rules
|
|| rand.below(nonzero!(100)) <= p_include_short_rules
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
//! Generators may generate bytes or, in general, data, for inputs.
|
//! Generators may generate bytes or, in general, data, for inputs.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{
|
use core::{marker::PhantomData, num::NonZeroUsize};
|
||||||
marker::PhantomData,
|
|
||||||
num::{NonZero, NonZeroUsize},
|
|
||||||
};
|
|
||||||
|
|
||||||
use libafl_bolts::rands::Rand;
|
use libafl_bolts::rands::Rand;
|
||||||
|
|
||||||
use crate::{inputs::bytes::BytesInput, state::HasRand, Error};
|
use crate::{inputs::bytes::BytesInput, nonzero, state::HasRand, Error};
|
||||||
|
|
||||||
pub mod gramatron;
|
pub mod gramatron;
|
||||||
|
use core::cmp::min;
|
||||||
|
|
||||||
pub use gramatron::*;
|
pub use gramatron::*;
|
||||||
|
|
||||||
#[cfg(feature = "nautilus")]
|
#[cfg(feature = "nautilus")]
|
||||||
@ -74,64 +73,45 @@ where
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Generates random bytes
|
/// Generates random bytes
|
||||||
pub struct RandBytesGenerator<S> {
|
pub struct RandBytesGenerator {
|
||||||
max_size: NonZeroUsize,
|
max_size: NonZeroUsize,
|
||||||
phantom: PhantomData<S>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Generator<BytesInput, S> for RandBytesGenerator<S>
|
impl<S> Generator<BytesInput, S> for RandBytesGenerator
|
||||||
where
|
where
|
||||||
S: HasRand,
|
S: HasRand,
|
||||||
{
|
{
|
||||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||||
let mut size = state.rand_mut().below(self.max_size);
|
let mut size = state.rand_mut().below(self.max_size);
|
||||||
if size == 0 {
|
size = min(size, 1);
|
||||||
size = 1;
|
|
||||||
}
|
|
||||||
let random_bytes: Vec<u8> = (0..size)
|
let random_bytes: Vec<u8> = (0..size)
|
||||||
.map(|_| state.rand_mut().below(NonZero::new(256).unwrap()) as u8)
|
.map(|_| state.rand_mut().below(nonzero!(256)) as u8)
|
||||||
.collect();
|
.collect();
|
||||||
Ok(BytesInput::new(random_bytes))
|
Ok(BytesInput::new(random_bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> RandBytesGenerator<S> {
|
impl RandBytesGenerator {
|
||||||
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
|
||||||
///
|
|
||||||
/// If you want to save one 0 check, use [`Self::from_nonzero`].
|
|
||||||
pub fn new(max_size: usize) -> Result<Self, Error> {
|
|
||||||
let Some(max_size) = NonZero::new(max_size) else {
|
|
||||||
return Err(Error::illegal_argument("The max_size may not be 0."));
|
|
||||||
};
|
|
||||||
Ok(Self::from_nonzero(max_size))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_nonzero(max_size: NonZeroUsize) -> Self {
|
pub fn new(max_size: NonZeroUsize) -> Self {
|
||||||
Self {
|
Self { max_size }
|
||||||
max_size,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
/// Generates random printable characters
|
/// Generates random printable characters
|
||||||
pub struct RandPrintablesGenerator<S> {
|
pub struct RandPrintablesGenerator {
|
||||||
max_size: NonZeroUsize,
|
max_size: NonZeroUsize,
|
||||||
phantom: PhantomData<S>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Generator<BytesInput, S> for RandPrintablesGenerator<S>
|
impl<S> Generator<BytesInput, S> for RandPrintablesGenerator
|
||||||
where
|
where
|
||||||
S: HasRand,
|
S: HasRand,
|
||||||
{
|
{
|
||||||
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
fn generate(&mut self, state: &mut S) -> Result<BytesInput, Error> {
|
||||||
let mut size = state.rand_mut().below(self.max_size);
|
let mut size = state.rand_mut().below(self.max_size);
|
||||||
if size == 0 {
|
size = min(size, 1);
|
||||||
size = 1;
|
|
||||||
}
|
|
||||||
let printables = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \t\n!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".as_bytes();
|
let printables = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \t\n!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".as_bytes();
|
||||||
let random_bytes: Vec<u8> = (0..size)
|
let random_bytes: Vec<u8> = (0..size)
|
||||||
.map(|_| *state.rand_mut().choose(printables).unwrap())
|
.map(|_| *state.rand_mut().choose(printables).unwrap())
|
||||||
@ -140,23 +120,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> RandPrintablesGenerator<S> {
|
impl RandPrintablesGenerator {
|
||||||
/// Creates a new [`RandPrintablesGenerator`], generating up to `max_size` random printable characters.
|
|
||||||
///
|
|
||||||
/// To skip the 0 `max_size` check, create this using [`Self::from_nonzero`] instead.
|
|
||||||
pub fn new(max_size: usize) -> Result<Self, Error> {
|
|
||||||
let Some(max_size) = NonZero::new(max_size) else {
|
|
||||||
return Err(Error::illegal_argument("The max_size may not be 0."));
|
|
||||||
};
|
|
||||||
Ok(Self::from_nonzero(max_size))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
/// Returns a new [`RandBytesGenerator`], generating up to `max_size` random bytes.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_nonzero(max_size: NonZeroUsize) -> Self {
|
pub fn new(max_size: NonZeroUsize) -> Self {
|
||||||
Self {
|
Self { max_size }
|
||||||
max_size,
|
|
||||||
phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ pub mod stages;
|
|||||||
pub mod state;
|
pub mod state;
|
||||||
|
|
||||||
pub use fuzzer::*;
|
pub use fuzzer::*;
|
||||||
pub use libafl_bolts::Error;
|
pub use libafl_bolts::{nonzero, Error};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many components by adding a glob import.
|
/// The purpose of this module is to alleviate imports of many components by adding a glob import.
|
||||||
#[cfg(feature = "prelude")]
|
#[cfg(feature = "prelude")]
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
mutations::{buffer_copy, buffer_self_copy, ARITH_MAX},
|
mutations::{buffer_copy, buffer_self_copy, ARITH_MAX},
|
||||||
MutationResult, Mutator, Named,
|
MutationResult, Mutator, Named,
|
||||||
},
|
},
|
||||||
random_corpus_id_with_disabled,
|
nonzero, random_corpus_id_with_disabled,
|
||||||
state::{HasCorpus, HasMaxSize, HasRand},
|
state::{HasCorpus, HasMaxSize, HasRand},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -126,8 +126,8 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedAddMutator {
|
|||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let val = state.rand_mut().choose(input.codes_mut()).unwrap();
|
let val = state.rand_mut().choose(input.codes_mut()).unwrap();
|
||||||
let num = 1 + state.rand_mut().below(NonZero::new(ARITH_MAX).unwrap()) as u32;
|
let num = 1 + state.rand_mut().below(nonzero!(ARITH_MAX)) as u32;
|
||||||
*val = match state.rand_mut().below(NonZero::new(2).unwrap()) {
|
*val = match state.rand_mut().below(nonzero!(2)) {
|
||||||
0 => val.wrapping_add(num),
|
0 => val.wrapping_add(num),
|
||||||
_ => val.wrapping_sub(num),
|
_ => val.wrapping_sub(num),
|
||||||
};
|
};
|
||||||
@ -205,7 +205,7 @@ where
|
|||||||
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
|
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
|
||||||
let max_size = state.max_size();
|
let max_size = state.max_size();
|
||||||
let size = input.codes().len();
|
let size = input.codes().len();
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ where
|
|||||||
let off = state
|
let off = state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
.below(unsafe { NonZero::new(size + 1).unwrap_unchecked() });
|
.below(unsafe { NonZero::new(size + 1).unwrap_unchecked() });
|
||||||
let mut len = 1 + state.rand_mut().below(nonzero_size);
|
let mut len = 1 + state.rand_mut().below(nz);
|
||||||
|
|
||||||
if size + len > max_size {
|
if size + len > max_size {
|
||||||
if max_size > size {
|
if max_size > size {
|
||||||
@ -266,17 +266,23 @@ pub struct EncodedCopyMutator;
|
|||||||
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
|
impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
|
||||||
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
|
fn mutate(&mut self, state: &mut S, input: &mut EncodedInput) -> Result<MutationResult, Error> {
|
||||||
let size = input.codes().len();
|
let size = input.codes().len();
|
||||||
let Some(size) = NonZero::new(size) else {
|
if size <= 1 {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let from = state.rand_mut().below(size);
|
// # Safety
|
||||||
let to = state.rand_mut().below(size);
|
// it's larger than 1
|
||||||
|
let from = state
|
||||||
|
.rand_mut()
|
||||||
|
.below(unsafe { NonZero::new(size).unwrap_unchecked() });
|
||||||
|
let to = state
|
||||||
|
.rand_mut()
|
||||||
|
.below(unsafe { NonZero::new(size).unwrap_unchecked() });
|
||||||
// # Safety
|
// # Safety
|
||||||
// Both from and to are smaller than size, so size minus any of these can never be 0.
|
// Both from and to are smaller than size, so size minus any of these can never be 0.
|
||||||
let len = 1 + state
|
let len = 1 + state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
.below(unsafe { NonZero::new(size.get() - max(from, to)).unwrap_unchecked() });
|
.below(unsafe { NonZero::new(size - max(from, to)).unwrap_unchecked() });
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
buffer_self_copy(input.codes_mut(), from, to, len);
|
buffer_self_copy(input.codes_mut(), from, to, len);
|
||||||
@ -321,7 +327,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(non_zero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -335,13 +341,13 @@ where
|
|||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(non_zero_other_size) = NonZero::new(other_size) else {
|
// # Safety
|
||||||
return Ok(MutationResult::Skipped);
|
// it's larger than 1
|
||||||
};
|
|
||||||
|
|
||||||
let max_size = state.max_size();
|
let max_size = state.max_size();
|
||||||
let from = state.rand_mut().below(non_zero_other_size);
|
let from = state
|
||||||
let to = state.rand_mut().below(non_zero_size);
|
.rand_mut()
|
||||||
|
.below(unsafe { NonZero::new(other_size).unwrap_unchecked() });
|
||||||
|
let to = state.rand_mut().below(nz);
|
||||||
// # Safety
|
// # Safety
|
||||||
// from is smaller than other_size, other_size is larger than 2, so the subtraction is larger than 0.
|
// from is smaller than other_size, other_size is larger than 2, so the subtraction is larger than 0.
|
||||||
let mut len = 1 + state
|
let mut len = 1 + state
|
||||||
@ -414,18 +420,18 @@ where
|
|||||||
if other_size < 2 {
|
if other_size < 2 {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
}
|
}
|
||||||
|
// # Safety
|
||||||
|
// other_size >= 2
|
||||||
|
let from = state
|
||||||
|
.rand_mut()
|
||||||
|
.below(unsafe { NonZero::new(other_size).unwrap_unchecked() });
|
||||||
|
|
||||||
let Some(non_zero_other_size) = NonZero::new(other_size) else {
|
// # Safety
|
||||||
return Ok(MutationResult::Skipped);
|
// size > 0, other_size > from,
|
||||||
};
|
let len = state
|
||||||
|
.rand_mut()
|
||||||
|
.below(unsafe { NonZero::new(min(other_size - from, size)).unwrap_unchecked() });
|
||||||
|
|
||||||
let from = state.rand_mut().below(non_zero_other_size);
|
|
||||||
|
|
||||||
let Some(non_zero_min_len) = NonZero::new(min(other_size - from, size)) else {
|
|
||||||
return Ok(MutationResult::Skipped);
|
|
||||||
};
|
|
||||||
|
|
||||||
let len = state.rand_mut().below(non_zero_min_len);
|
|
||||||
// # Safety
|
// # Safety
|
||||||
// size is non-zero, len is below min(size, ...), so the subtraction will always be positive.
|
// size is non-zero, len is below min(size, ...), so the subtraction will always be positive.
|
||||||
let to = state
|
let to = state
|
||||||
|
@ -16,7 +16,7 @@ use crate::{
|
|||||||
generators::GramatronGenerator,
|
generators::GramatronGenerator,
|
||||||
inputs::{GramatronInput, Terminal},
|
inputs::{GramatronInput, Terminal},
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
random_corpus_id,
|
nonzero, random_corpus_id,
|
||||||
state::{HasCorpus, HasRand},
|
state::{HasCorpus, HasRand},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
@ -222,12 +222,12 @@ where
|
|||||||
let chosen = *state.rand_mut().choose(&self.states).unwrap();
|
let chosen = *state.rand_mut().choose(&self.states).unwrap();
|
||||||
let chosen_nums = self.counters.get(&chosen).unwrap().0;
|
let chosen_nums = self.counters.get(&chosen).unwrap().0;
|
||||||
|
|
||||||
let Some(non_zero_chosen_nums_minus_one) = NonZero::new(chosen_nums - 1) else {
|
let Some(minus_one) = NonZero::new(chosen_nums - 1) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
||||||
let mut first = state.rand_mut().below(non_zero_chosen_nums_minus_one) as i64;
|
let mut first = state.rand_mut().below(minus_one) as i64;
|
||||||
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
#[allow(clippy::cast_sign_loss, clippy::pedantic)]
|
||||||
let mut second = state
|
let mut second = state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
@ -259,10 +259,7 @@ where
|
|||||||
|
|
||||||
input.terminals_mut().truncate(idx_1);
|
input.terminals_mut().truncate(idx_1);
|
||||||
|
|
||||||
for _ in 0..state
|
for _ in 0..state.rand_mut().below(nonzero!(RECUR_THRESHOLD)) {
|
||||||
.rand_mut()
|
|
||||||
.below(NonZero::new(RECUR_THRESHOLD).unwrap())
|
|
||||||
{
|
|
||||||
input.terminals_mut().extend_from_slice(&self.feature);
|
input.terminals_mut().extend_from_slice(&self.feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +259,11 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let gen = generalised_meta.generalized_mut();
|
||||||
|
let Some(_) = NonZero::new(gen.len()) else {
|
||||||
|
return Err(Error::illegal_state("No generalized metadata found."));
|
||||||
|
};
|
||||||
|
|
||||||
let token_find = state.rand_mut().below(tokens_len);
|
let token_find = state.rand_mut().below(tokens_len);
|
||||||
let mut token_replace = state.rand_mut().below(tokens_len);
|
let mut token_replace = state.rand_mut().below(tokens_len);
|
||||||
if token_find == token_replace {
|
if token_find == token_replace {
|
||||||
@ -274,11 +279,11 @@ where
|
|||||||
|
|
||||||
let mut mutated = MutationResult::Skipped;
|
let mut mutated = MutationResult::Skipped;
|
||||||
|
|
||||||
let gen = generalised_meta.generalized_mut();
|
// # Safety
|
||||||
let rand_idx = fast_bound(
|
// gen.len() is positive.
|
||||||
rand_idx,
|
let rand_idx = fast_bound(rand_idx, unsafe {
|
||||||
NonZero::new(gen.len()).ok_or_else(|| Error::empty("No Generalized Metadata found"))?,
|
NonZero::new(gen.len()).unwrap_unchecked()
|
||||||
);
|
});
|
||||||
|
|
||||||
'first: for item in &mut gen[..rand_idx] {
|
'first: for item in &mut gen[..rand_idx] {
|
||||||
if let GeneralizedItem::Bytes(bytes) = item {
|
if let GeneralizedItem::Bytes(bytes) = item {
|
||||||
|
@ -3,10 +3,7 @@
|
|||||||
//! It uses a modified Particle Swarm Optimization algorithm to determine an optimal distribution of mutators.
|
//! It uses a modified Particle Swarm Optimization algorithm to determine an optimal distribution of mutators.
|
||||||
//! See <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
|
//! See <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
|
||||||
use alloc::{borrow::Cow, string::ToString, vec::Vec};
|
use alloc::{borrow::Cow, string::ToString, vec::Vec};
|
||||||
use core::{
|
use core::fmt::{self, Debug};
|
||||||
fmt::{self, Debug},
|
|
||||||
num::{NonZero, NonZeroUsize},
|
|
||||||
};
|
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
rands::{Rand, StdRand},
|
rands::{Rand, StdRand},
|
||||||
@ -370,7 +367,7 @@ pub struct StdMOptMutator<MT> {
|
|||||||
mode: MOptMode,
|
mode: MOptMode,
|
||||||
finds_before: usize,
|
finds_before: usize,
|
||||||
mutations: MT,
|
mutations: MT,
|
||||||
max_stack_pow: NonZeroUsize,
|
max_stack_pow: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, S> Mutator<I, S> for StdMOptMutator<MT>
|
impl<I, MT, S> Mutator<I, S> for StdMOptMutator<MT>
|
||||||
@ -514,11 +511,7 @@ impl<MT> StdMOptMutator<MT> {
|
|||||||
let rand_seed = state.rand_mut().next();
|
let rand_seed = state.rand_mut().next();
|
||||||
state.add_metadata::<MOpt>(MOpt::new(MT::LEN, swarm_num, rand_seed)?);
|
state.add_metadata::<MOpt>(MOpt::new(MT::LEN, swarm_num, rand_seed)?);
|
||||||
}
|
}
|
||||||
let Some(max_stack_pow) = NonZero::new(max_stack_pow) else {
|
|
||||||
return Err(Error::illegal_argument(
|
|
||||||
"Got 0 as value for max_stack_pow in StdMOptMutator.",
|
|
||||||
));
|
|
||||||
};
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name: Cow::from(format!("StdMOptMutator[{}]", mutations.names().join(","))),
|
name: Cow::from(format!("StdMOptMutator[{}]", mutations.names().join(","))),
|
||||||
mode: MOptMode::Pilotfuzzing,
|
mode: MOptMode::Pilotfuzzing,
|
||||||
@ -618,7 +611,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
||||||
1 << (1 + state.rand_mut().below(self.max_stack_pow))
|
1 << (1 + state.rand_mut().zero_upto(self.max_stack_pow))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next mutation to apply
|
/// Get the next mutation to apply
|
||||||
|
@ -156,10 +156,10 @@ where
|
|||||||
.map(|(id, part)| (id, part.bytes().len()));
|
.map(|(id, part)| (id, part.bytes().len()));
|
||||||
|
|
||||||
if let Some((part_idx, size)) = maybe_size {
|
if let Some((part_idx, size)) = maybe_size {
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
let target = state.rand_mut().below(nonzero_size);
|
let target = state.rand_mut().below(nz);
|
||||||
// # Safety
|
// # Safety
|
||||||
// size is nonzero here (checked above), target is smaller than size
|
// size is nonzero here (checked above), target is smaller than size
|
||||||
// -> the subtraction result is greater than 0.
|
// -> the subtraction result is greater than 0.
|
||||||
@ -212,11 +212,11 @@ where
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
drop(other_testcase);
|
drop(other_testcase);
|
||||||
let size = part.bytes().len();
|
let size = part.bytes().len();
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = state.rand_mut().below(nonzero_size);
|
let target = state.rand_mut().below(nz);
|
||||||
// # Safety
|
// # Safety
|
||||||
// other_size is larger than 0, checked above.
|
// other_size is larger than 0, checked above.
|
||||||
// size is larger than 0.
|
// size is larger than 0.
|
||||||
@ -285,11 +285,11 @@ where
|
|||||||
.map(|(id, part)| (id, part.bytes().len()));
|
.map(|(id, part)| (id, part.bytes().len()));
|
||||||
|
|
||||||
if let Some((part_idx, size)) = maybe_size {
|
if let Some((part_idx, size)) = maybe_size {
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = state.rand_mut().below(nonzero_size);
|
let target = state.rand_mut().below(nz);
|
||||||
// # Safety
|
// # Safety
|
||||||
// other_size is checked above.
|
// other_size is checked above.
|
||||||
// size is larger than than target and larger than 1. The subtraction result will always be positive.
|
// size is larger than than target and larger than 1. The subtraction result will always be positive.
|
||||||
@ -335,11 +335,11 @@ where
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
drop(other_testcase);
|
drop(other_testcase);
|
||||||
let size = part.bytes().len();
|
let size = part.bytes().len();
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let Some(nz) = NonZero::new(size) else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
let target = state.rand_mut().below(nonzero_size);
|
let target = state.rand_mut().below(nz);
|
||||||
// # Safety
|
// # Safety
|
||||||
// other_size is checked above.
|
// other_size is checked above.
|
||||||
// size is larger than than target and larger than 1. The subtraction result will always be positive.
|
// size is larger than than target and larger than 1. The subtraction result will always be positive.
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
inputs::HasMutatorBytes,
|
inputs::HasMutatorBytes,
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
random_corpus_id_with_disabled,
|
nonzero, random_corpus_id_with_disabled,
|
||||||
state::{HasCorpus, HasMaxSize, HasRand},
|
state::{HasCorpus, HasMaxSize, HasRand},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -73,10 +73,7 @@ pub fn buffer_set<T: Clone>(data: &mut [T], from: usize, len: usize, val: T) {
|
|||||||
pub fn rand_range<S: HasRand>(state: &mut S, upper: usize, max_len: NonZeroUsize) -> Range<usize> {
|
pub fn rand_range<S: HasRand>(state: &mut S, upper: usize, max_len: NonZeroUsize) -> Range<usize> {
|
||||||
let len = 1 + state.rand_mut().below(max_len);
|
let len = 1 + state.rand_mut().below(max_len);
|
||||||
// sample from [1..upper + len]
|
// sample from [1..upper + len]
|
||||||
let Some(upper_len_minus1) = NonZero::new(upper + len - 1) else {
|
let mut offset2 = 1 + state.rand_mut().zero_upto(upper + len - 1);
|
||||||
return 0..0;
|
|
||||||
};
|
|
||||||
let mut offset2 = 1 + state.rand_mut().below(upper_len_minus1);
|
|
||||||
let offset1 = offset2.saturating_sub(len);
|
let offset1 = offset2.saturating_sub(len);
|
||||||
if offset2 > upper {
|
if offset2 > upper {
|
||||||
offset2 = upper;
|
offset2 = upper;
|
||||||
@ -314,7 +311,7 @@ where
|
|||||||
Ok(MutationResult::Skipped)
|
Ok(MutationResult::Skipped)
|
||||||
} else {
|
} else {
|
||||||
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
let byte = state.rand_mut().choose(input.bytes_mut()).unwrap();
|
||||||
*byte ^= 1 + state.rand_mut().below(NonZero::new(254).unwrap()) as u8;
|
*byte ^= 1 + state.rand_mut().below(nonzero!(254)) as u8;
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,8 +362,8 @@ macro_rules! add_mutator_impl {
|
|||||||
let val = <$size>::from_ne_bytes(bytes.try_into().unwrap());
|
let val = <$size>::from_ne_bytes(bytes.try_into().unwrap());
|
||||||
|
|
||||||
// mutate
|
// mutate
|
||||||
let num = 1 + state.rand_mut().below(NonZero::new(ARITH_MAX).unwrap()) as $size;
|
let num = 1 + state.rand_mut().below(nonzero!(ARITH_MAX)) as $size;
|
||||||
let new_val = match state.rand_mut().below(NonZero::new(4).unwrap()) {
|
let new_val = match state.rand_mut().below(nonzero!(4)) {
|
||||||
0 => val.wrapping_add(num),
|
0 => val.wrapping_add(num),
|
||||||
1 => val.wrapping_sub(num),
|
1 => val.wrapping_sub(num),
|
||||||
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
|
2 => val.swap_bytes().wrapping_add(num).swap_bytes(),
|
||||||
@ -569,7 +566,7 @@ where
|
|||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut amount = 1 + state.rand_mut().below(NonZero::new(16).unwrap());
|
let mut amount = 1 + state.rand_mut().below(nonzero!(16));
|
||||||
// # Safety
|
// # Safety
|
||||||
// It's a safe assumption that size + 1 is never 0.
|
// It's a safe assumption that size + 1 is never 0.
|
||||||
// If we wrap around we have _a lot_ of elements - and the code will break later anyway.
|
// If we wrap around we have _a lot_ of elements - and the code will break later anyway.
|
||||||
@ -632,7 +629,7 @@ where
|
|||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut amount = 1 + state.rand_mut().below(NonZero::new(16).unwrap());
|
let mut amount = 1 + state.rand_mut().below(nonzero!(16));
|
||||||
// # Safety
|
// # Safety
|
||||||
// size + 1 can never be 0
|
// size + 1 can never be 0
|
||||||
let offset = state
|
let offset = state
|
||||||
@ -835,9 +832,9 @@ where
|
|||||||
let max_insert_len = min(size - target, state.max_size() - size);
|
let max_insert_len = min(size - target, state.max_size() - size);
|
||||||
let max_insert_len = min(16, max_insert_len);
|
let max_insert_len = min(16, max_insert_len);
|
||||||
|
|
||||||
let Some(max_insert_len) = NonZero::new(max_insert_len) else {
|
// # Safety
|
||||||
return Ok(MutationResult::Skipped);
|
// size > target and state.max_size() > size
|
||||||
};
|
let max_insert_len = unsafe { NonZero::new(max_insert_len).unwrap_unchecked() };
|
||||||
|
|
||||||
let range = rand_range(state, size, max_insert_len);
|
let range = rand_range(state, size, max_insert_len);
|
||||||
|
|
||||||
@ -989,13 +986,6 @@ where
|
|||||||
}
|
}
|
||||||
Ok(MutationResult::Mutated)
|
Ok(MutationResult::Mutated)
|
||||||
} else if first.end != size {
|
} else if first.end != size {
|
||||||
// The first range comes before the second range
|
|
||||||
debug_assert!(
|
|
||||||
first.end < size,
|
|
||||||
"First.end ({}) should never be larger than size ({})!",
|
|
||||||
first.end,
|
|
||||||
size
|
|
||||||
);
|
|
||||||
// # Safety
|
// # Safety
|
||||||
// first.end is not equal to size, so subtracting them can never be 0.
|
// first.end is not equal to size, so subtracting them can never be 0.
|
||||||
let mut second = rand_range(state, size - first.end, unsafe {
|
let mut second = rand_range(state, size - first.end, unsafe {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use alloc::{borrow::Cow, vec::Vec};
|
use alloc::{borrow::Cow, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
num::{NonZero, NonZeroUsize},
|
num::NonZero,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,6 +21,7 @@ use crate::{
|
|||||||
token_mutations::{TokenInsert, TokenReplace},
|
token_mutations::{TokenInsert, TokenReplace},
|
||||||
MutationResult, Mutator, MutatorsTuple,
|
MutationResult, Mutator, MutatorsTuple,
|
||||||
},
|
},
|
||||||
|
nonzero,
|
||||||
state::{HasCorpus, HasRand},
|
state::{HasCorpus, HasRand},
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
};
|
};
|
||||||
@ -102,7 +103,7 @@ where
|
|||||||
pub struct StdScheduledMutator<MT> {
|
pub struct StdScheduledMutator<MT> {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
mutations: MT,
|
mutations: MT,
|
||||||
max_stack_pow: NonZeroUsize,
|
max_stack_pow: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MT> Named for StdScheduledMutator<MT> {
|
impl<MT> Named for StdScheduledMutator<MT> {
|
||||||
@ -144,7 +145,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
||||||
1 << (1 + state.rand_mut().below(self.max_stack_pow))
|
1 << (1 + state.rand_mut().zero_upto(self.max_stack_pow))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next mutation to apply
|
/// Get the next mutation to apply
|
||||||
@ -171,7 +172,7 @@ where
|
|||||||
mutations.names().join(", ")
|
mutations.names().join(", ")
|
||||||
)),
|
)),
|
||||||
mutations,
|
mutations,
|
||||||
max_stack_pow: NonZero::new(7).unwrap(),
|
max_stack_pow: 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,18 +181,15 @@ where
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will return [`Error::IllegalArgument`] for `max_stack_pow` of 0.
|
/// Will return [`Error::IllegalArgument`] for `max_stack_pow` of 0.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: usize) -> Result<Self, Error> {
|
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: usize) -> Self {
|
||||||
let Some(max_stack_pow) = NonZero::new(max_stack_pow) else {
|
Self {
|
||||||
return Err(Error::illegal_argument("Max stack pow may not be 0."));
|
|
||||||
};
|
|
||||||
Ok(Self {
|
|
||||||
name: Cow::from(format!(
|
name: Cow::from(format!(
|
||||||
"StdScheduledMutator[{}]",
|
"StdScheduledMutator[{}]",
|
||||||
mutations.names().join(", ")
|
mutations.names().join(", ")
|
||||||
)),
|
)),
|
||||||
mutations,
|
mutations,
|
||||||
max_stack_pow,
|
max_stack_pow,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +264,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Compute the number of iterations used to apply stacked mutations
|
/// Compute the number of iterations used to apply stacked mutations
|
||||||
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
fn iterations(&self, state: &mut S, _: &I) -> u64 {
|
||||||
1 << (1 + state.rand_mut().below(NonZero::new(6).unwrap()))
|
1 << (1 + state.rand_mut().below(nonzero!(7)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next mutation to apply
|
/// Get the next mutation to apply
|
||||||
|
@ -323,9 +323,12 @@ where
|
|||||||
let token_idx = state.rand_mut().below(tokens_len);
|
let token_idx = state.rand_mut().below(tokens_len);
|
||||||
|
|
||||||
let size = input.bytes().len();
|
let size = input.bytes().len();
|
||||||
|
// # Safety
|
||||||
|
// after saturating add it's always above 0
|
||||||
|
|
||||||
let off = state
|
let off = state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
.below(NonZero::new(size.wrapping_add(1)).unwrap());
|
.below(unsafe { NonZero::new(size.saturating_add(1)).unwrap_unchecked() });
|
||||||
|
|
||||||
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
||||||
let token = &meta.tokens()[token_idx];
|
let token = &meta.tokens()[token_idx];
|
||||||
@ -376,7 +379,9 @@ where
|
|||||||
{
|
{
|
||||||
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
fn mutate(&mut self, state: &mut S, input: &mut I) -> Result<MutationResult, Error> {
|
||||||
let size = input.bytes().len();
|
let size = input.bytes().len();
|
||||||
let Some(nonzero_size) = NonZero::new(size) else {
|
let off = if let Some(nz) = NonZero::new(size) {
|
||||||
|
state.rand_mut().below(nz)
|
||||||
|
} else {
|
||||||
return Ok(MutationResult::Skipped);
|
return Ok(MutationResult::Skipped);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -392,8 +397,6 @@ where
|
|||||||
};
|
};
|
||||||
let token_idx = state.rand_mut().below(tokens_len);
|
let token_idx = state.rand_mut().below(tokens_len);
|
||||||
|
|
||||||
let off = state.rand_mut().below(nonzero_size);
|
|
||||||
|
|
||||||
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
let meta = state.metadata_map().get::<Tokens>().unwrap();
|
||||||
let token = &meta.tokens()[token_idx];
|
let token = &meta.tokens()[token_idx];
|
||||||
let mut len = token.len();
|
let mut len = token.len();
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
//! a specific mutator for a specified amount of iterations
|
//! a specific mutator for a specified amount of iterations
|
||||||
|
|
||||||
use alloc::{borrow::Cow, vec::Vec};
|
use alloc::{borrow::Cow, vec::Vec};
|
||||||
use core::{
|
use core::{fmt::Debug, num::NonZero};
|
||||||
fmt::Debug,
|
|
||||||
num::{NonZero, NonZeroUsize},
|
|
||||||
};
|
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
impl_serdeany, math::calculate_cumulative_distribution_in_place, rands::Rand,
|
impl_serdeany, math::calculate_cumulative_distribution_in_place, rands::Rand,
|
||||||
@ -86,7 +83,7 @@ impl TuneableScheduledMutatorMetadata {
|
|||||||
pub struct TuneableScheduledMutator<MT> {
|
pub struct TuneableScheduledMutator<MT> {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
mutations: MT,
|
mutations: MT,
|
||||||
max_stack_pow: NonZeroUsize,
|
max_stack_pow: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, MT, S> Mutator<I, S> for TuneableScheduledMutator<MT>
|
impl<I, MT, S> Mutator<I, S> for TuneableScheduledMutator<MT>
|
||||||
@ -135,7 +132,7 @@ where
|
|||||||
iters
|
iters
|
||||||
} else {
|
} else {
|
||||||
// fall back to random
|
// fall back to random
|
||||||
1 << (1 + state.rand_mut().below(self.max_stack_pow))
|
1 << (1 + state.rand_mut().zero_upto(self.max_stack_pow))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We will sample using the mutation probabilities.
|
// We will sample using the mutation probabilities.
|
||||||
@ -218,7 +215,7 @@ impl<MT> TuneableScheduledMutator<MT> {
|
|||||||
TuneableScheduledMutator {
|
TuneableScheduledMutator {
|
||||||
name: Cow::from(format!("TuneableMutator[{}]", mutations.names().join(", "))),
|
name: Cow::from(format!("TuneableMutator[{}]", mutations.names().join(", "))),
|
||||||
mutations,
|
mutations,
|
||||||
max_stack_pow: NonZero::new(7).unwrap(),
|
max_stack_pow: 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ use crate::{
|
|||||||
corpus::{Corpus, CorpusId, HasTestcase, Testcase},
|
corpus::{Corpus, CorpusId, HasTestcase, Testcase},
|
||||||
inputs::{BytesInput, HasMutatorBytes},
|
inputs::{BytesInput, HasMutatorBytes},
|
||||||
mutators::{rand_range, MutationResult, Mutator, Tokens},
|
mutators::{rand_range, MutationResult, Mutator, Tokens},
|
||||||
|
nonzero,
|
||||||
stages::{
|
stages::{
|
||||||
extract_metadata,
|
extract_metadata,
|
||||||
mutational::{MutatedTransform, MutatedTransformPost},
|
mutational::{MutatedTransform, MutatedTransformPost},
|
||||||
@ -233,11 +234,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
|||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
char_gen: F,
|
char_gen: F,
|
||||||
) -> MutationResult {
|
) -> MutationResult {
|
||||||
let temp_range = rand_range(
|
let temp_range = rand_range(state, range.end - range.start, nonzero!(MAX_CHARS));
|
||||||
state,
|
|
||||||
range.end - range.start,
|
|
||||||
NonZero::new(MAX_CHARS).unwrap(),
|
|
||||||
);
|
|
||||||
let range = (range.start + temp_range.start)..(range.start + temp_range.end);
|
let range = (range.start + temp_range.start)..(range.start + temp_range.end);
|
||||||
let range = match core::str::from_utf8(&input.0.bytes()[range.clone()]) {
|
let range = match core::str::from_utf8(&input.0.bytes()[range.clone()]) {
|
||||||
Ok(_) => range,
|
Ok(_) => range,
|
||||||
@ -254,7 +251,7 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
|
|||||||
return MutationResult::Skipped;
|
return MutationResult::Skipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
let replace_len = state.rand_mut().below(NonZero::new(MAX_CHARS).unwrap());
|
let replace_len = state.rand_mut().below(nonzero!(MAX_CHARS));
|
||||||
let orig_len = range.end - range.start;
|
let orig_len = range.end - range.start;
|
||||||
if input.0.len() - orig_len + replace_len > state.max_size() {
|
if input.0.len() - orig_len + replace_len > state.max_size() {
|
||||||
return MutationResult::Skipped;
|
return MutationResult::Skipped;
|
||||||
|
@ -4,7 +4,7 @@ use alloc::{
|
|||||||
collections::binary_heap::BinaryHeap,
|
collections::binary_heap::BinaryHeap,
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, num::NonZero, ops::Range};
|
use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, ops::Range};
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
rands::Rand,
|
rands::Rand,
|
||||||
@ -19,6 +19,7 @@ use crate::{
|
|||||||
executors::{Executor, HasObservers},
|
executors::{Executor, HasObservers},
|
||||||
inputs::{HasMutatorBytes, UsesInput},
|
inputs::{HasMutatorBytes, UsesInput},
|
||||||
mutators::mutations::buffer_copy,
|
mutators::mutations::buffer_copy,
|
||||||
|
nonzero,
|
||||||
observers::{MapObserver, ObserversTuple},
|
observers::{MapObserver, ObserversTuple},
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasRand, UsesState},
|
state::{HasCorpus, HasCurrentTestcase, HasRand, UsesState},
|
||||||
@ -353,11 +354,11 @@ where
|
|||||||
let c = match bytes[idx] {
|
let c = match bytes[idx] {
|
||||||
0x41..=0x46 => {
|
0x41..=0x46 => {
|
||||||
// 'A' + 1 + rand('F' - 'A')
|
// 'A' + 1 + rand('F' - 'A')
|
||||||
0x41 + 1 + state.rand_mut().below(NonZero::new(5).unwrap()) as u8
|
0x41 + 1 + state.rand_mut().below(nonzero!(5)) as u8
|
||||||
}
|
}
|
||||||
0x61..=0x66 => {
|
0x61..=0x66 => {
|
||||||
// 'a' + 1 + rand('f' - 'a')
|
// 'a' + 1 + rand('f' - 'a')
|
||||||
0x61 + 1 + state.rand_mut().below(NonZero::new(5).unwrap()) as u8
|
0x61 + 1 + state.rand_mut().below(nonzero!(5)) as u8
|
||||||
}
|
}
|
||||||
0x30 => {
|
0x30 => {
|
||||||
// '0' -> '1'
|
// '0' -> '1'
|
||||||
@ -369,35 +370,35 @@ where
|
|||||||
}
|
}
|
||||||
0x32..=0x39 => {
|
0x32..=0x39 => {
|
||||||
// '2' + 1 + rand('9' - '2')
|
// '2' + 1 + rand('9' - '2')
|
||||||
0x32 + 1 + state.rand_mut().below(NonZero::new(7).unwrap()) as u8
|
0x32 + 1 + state.rand_mut().below(nonzero!(7)) as u8
|
||||||
}
|
}
|
||||||
0x47..=0x5a => {
|
0x47..=0x5a => {
|
||||||
// 'G' + 1 + rand('Z' - 'G')
|
// 'G' + 1 + rand('Z' - 'G')
|
||||||
0x47 + 1 + state.rand_mut().below(NonZero::new(19).unwrap()) as u8
|
0x47 + 1 + state.rand_mut().below(nonzero!(19)) as u8
|
||||||
}
|
}
|
||||||
0x67..=0x7a => {
|
0x67..=0x7a => {
|
||||||
// 'g' + 1 + rand('z' - 'g')
|
// 'g' + 1 + rand('z' - 'g')
|
||||||
0x67 + 1 + state.rand_mut().below(NonZero::new(19).unwrap()) as u8
|
0x67 + 1 + state.rand_mut().below(nonzero!(19)) as u8
|
||||||
}
|
}
|
||||||
0x21..=0x2a => {
|
0x21..=0x2a => {
|
||||||
// '!' + 1 + rand('*' - '!');
|
// '!' + 1 + rand('*' - '!');
|
||||||
0x21 + 1 + state.rand_mut().below(NonZero::new(9).unwrap()) as u8
|
0x21 + 1 + state.rand_mut().below(nonzero!(9)) as u8
|
||||||
}
|
}
|
||||||
0x2c..=0x2e => {
|
0x2c..=0x2e => {
|
||||||
// ',' + 1 + rand('.' - ',')
|
// ',' + 1 + rand('.' - ',')
|
||||||
0x2c + 1 + state.rand_mut().below(NonZero::new(2).unwrap()) as u8
|
0x2c + 1 + state.rand_mut().below(nonzero!(2)) as u8
|
||||||
}
|
}
|
||||||
0x3a..=0x40 => {
|
0x3a..=0x40 => {
|
||||||
// ':' + 1 + rand('@' - ':')
|
// ':' + 1 + rand('@' - ':')
|
||||||
0x3a + 1 + state.rand_mut().below(NonZero::new(6).unwrap()) as u8
|
0x3a + 1 + state.rand_mut().below(nonzero!(6)) as u8
|
||||||
}
|
}
|
||||||
0x5b..=0x60 => {
|
0x5b..=0x60 => {
|
||||||
// '[' + 1 + rand('`' - '[')
|
// '[' + 1 + rand('`' - '[')
|
||||||
0x5b + 1 + state.rand_mut().below(NonZero::new(5).unwrap()) as u8
|
0x5b + 1 + state.rand_mut().below(nonzero!(5)) as u8
|
||||||
}
|
}
|
||||||
0x7b..=0x7e => {
|
0x7b..=0x7e => {
|
||||||
// '{' + 1 + rand('~' - '{')
|
// '{' + 1 + rand('~' - '{')
|
||||||
0x7b + 1 + state.rand_mut().below(NonZero::new(3).unwrap()) as u8
|
0x7b + 1 + state.rand_mut().below(nonzero!(3)) as u8
|
||||||
}
|
}
|
||||||
0x2b => {
|
0x2b => {
|
||||||
// '+' -> '/'
|
// '+' -> '/'
|
||||||
|
@ -5,10 +5,7 @@ use alloc::{
|
|||||||
borrow::{Cow, ToOwned},
|
borrow::{Cow, ToOwned},
|
||||||
string::ToString,
|
string::ToString,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{marker::PhantomData, num::NonZeroUsize};
|
||||||
marker::PhantomData,
|
|
||||||
num::{NonZero, NonZeroUsize},
|
|
||||||
};
|
|
||||||
|
|
||||||
use libafl_bolts::{rands::Rand, Named};
|
use libafl_bolts::{rands::Rand, Named};
|
||||||
|
|
||||||
@ -18,6 +15,7 @@ use crate::{
|
|||||||
inputs::Input,
|
inputs::Input,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MultiMutator, MutationResult, Mutator},
|
mutators::{MultiMutator, MutationResult, Mutator},
|
||||||
|
nonzero,
|
||||||
stages::{RetryCountRestartHelper, Stage},
|
stages::{RetryCountRestartHelper, Stage},
|
||||||
start_timer,
|
start_timer,
|
||||||
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasRand, UsesState},
|
state::{HasCorpus, HasCurrentTestcase, HasExecutions, HasRand, UsesState},
|
||||||
@ -155,7 +153,7 @@ where
|
|||||||
|
|
||||||
/// Default value, how many iterations each stage gets, as an upper bound.
|
/// Default value, how many iterations each stage gets, as an upper bound.
|
||||||
/// It may randomly continue earlier.
|
/// It may randomly continue earlier.
|
||||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
pub const DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
||||||
|
|
||||||
/// The default mutational stage
|
/// The default mutational stage
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -263,12 +261,12 @@ where
|
|||||||
/// Creates a new default mutational stage
|
/// Creates a new default mutational stage
|
||||||
pub fn new(mutator: M) -> Self {
|
pub fn new(mutator: M) -> Self {
|
||||||
// Safe to unwrap: DEFAULT_MUTATIONAL_MAX_ITERATIONS is never 0.
|
// Safe to unwrap: DEFAULT_MUTATIONAL_MAX_ITERATIONS is never 0.
|
||||||
Self::transforming_with_max_iterations(mutator, DEFAULT_MUTATIONAL_MAX_ITERATIONS).unwrap()
|
Self::transforming_with_max_iterations(mutator, nonzero!(DEFAULT_MUTATIONAL_MAX_ITERATIONS))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new mutational stage with the given max iterations
|
/// Creates a new mutational stage with the given max iterations
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_max_iterations(mutator: M, max_iterations: usize) -> Result<Self, Error> {
|
pub fn with_max_iterations(mutator: M, max_iterations: NonZeroUsize) -> Self {
|
||||||
Self::transforming_with_max_iterations(mutator, max_iterations)
|
Self::transforming_with_max_iterations(mutator, max_iterations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,7 +282,7 @@ where
|
|||||||
/// Creates a new transforming mutational stage with the default max iterations
|
/// Creates a new transforming mutational stage with the default max iterations
|
||||||
pub fn transforming(mutator: M) -> Self {
|
pub fn transforming(mutator: M) -> Self {
|
||||||
// Safe to unwrap: DEFAULT_MUTATIONAL_MAX_ITERATIONS is never 0.
|
// Safe to unwrap: DEFAULT_MUTATIONAL_MAX_ITERATIONS is never 0.
|
||||||
Self::transforming_with_max_iterations(mutator, DEFAULT_MUTATIONAL_MAX_ITERATIONS).unwrap()
|
Self::transforming_with_max_iterations(mutator, nonzero!(DEFAULT_MUTATIONAL_MAX_ITERATIONS))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new transforming mutational stage with the given max iterations
|
/// Creates a new transforming mutational stage with the given max iterations
|
||||||
@ -292,14 +290,7 @@ where
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will return [`Error::IllegalArgument`] for `max_iterations` of 0.
|
/// Will return [`Error::IllegalArgument`] for `max_iterations` of 0.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transforming_with_max_iterations(
|
pub fn transforming_with_max_iterations(mutator: M, max_iterations: NonZeroUsize) -> Self {
|
||||||
mutator: M,
|
|
||||||
max_iterations: usize,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
// unsafe but impossible that you create two threads both instantiating this instance
|
|
||||||
let Some(max_iterations) = NonZero::new(max_iterations) else {
|
|
||||||
return Err(Error::illegal_argument("0 max iterations is not allowed.."));
|
|
||||||
};
|
|
||||||
let stage_id = unsafe {
|
let stage_id = unsafe {
|
||||||
let ret = MUTATIONAL_STAGE_ID;
|
let ret = MUTATIONAL_STAGE_ID;
|
||||||
MUTATIONAL_STAGE_ID += 1;
|
MUTATIONAL_STAGE_ID += 1;
|
||||||
@ -307,12 +298,12 @@ where
|
|||||||
};
|
};
|
||||||
let name =
|
let name =
|
||||||
Cow::Owned(MUTATIONAL_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str());
|
Cow::Owned(MUTATIONAL_STAGE_NAME.to_owned() + ":" + stage_id.to_string().as_str());
|
||||||
Ok(Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
mutator,
|
mutator,
|
||||||
max_iterations,
|
max_iterations,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ use alloc::rc::Rc;
|
|||||||
use core::{
|
use core::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
num::NonZero,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::rands::Rand;
|
use libafl_bolts::rands::Rand;
|
||||||
@ -19,6 +18,7 @@ use crate::{
|
|||||||
inputs::UsesInput,
|
inputs::UsesInput,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::Mutator,
|
mutators::Mutator,
|
||||||
|
nonzero,
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
schedulers::Scheduler,
|
schedulers::Scheduler,
|
||||||
start_timer,
|
start_timer,
|
||||||
@ -29,7 +29,7 @@ use crate::{
|
|||||||
use crate::{monitors::PerfFeature, state::HasClientPerfMonitor};
|
use crate::{monitors::PerfFeature, state::HasClientPerfMonitor};
|
||||||
|
|
||||||
/// The default maximum number of mutations to perform per input.
|
/// The default maximum number of mutations to perform per input.
|
||||||
pub static DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
pub const DEFAULT_MUTATIONAL_MAX_ITERATIONS: usize = 128;
|
||||||
|
|
||||||
/// A Mutational push stage is the stage in a fuzzing run that mutates inputs.
|
/// A Mutational push stage is the stage in a fuzzing run that mutates inputs.
|
||||||
///
|
///
|
||||||
@ -74,7 +74,7 @@ where
|
|||||||
fn iterations(&self, state: &mut Z::State, _corpus_id: CorpusId) -> Result<usize, Error> {
|
fn iterations(&self, state: &mut Z::State, _corpus_id: CorpusId) -> Result<usize, Error> {
|
||||||
Ok(1 + state
|
Ok(1 + state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
.below(NonZero::new(DEFAULT_MUTATIONAL_MAX_ITERATIONS).unwrap()))
|
.below(nonzero!(DEFAULT_MUTATIONAL_MAX_ITERATIONS)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current corpus index
|
/// Sets the current corpus index
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! A [`crate::stages::MutationalStage`] where the mutator iteration can be tuned at runtime
|
//! A [`crate::stages::MutationalStage`] where the mutator iteration can be tuned at runtime
|
||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use core::{marker::PhantomData, num::NonZero, time::Duration};
|
use core::{marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
use libafl_bolts::{current_time, impl_serdeany, rands::Rand};
|
use libafl_bolts::{current_time, impl_serdeany, rands::Rand};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -10,6 +10,7 @@ use crate::{
|
|||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
mark_feature_time,
|
mark_feature_time,
|
||||||
mutators::{MutationResult, Mutator},
|
mutators::{MutationResult, Mutator},
|
||||||
|
nonzero,
|
||||||
stages::{
|
stages::{
|
||||||
mutational::{MutatedTransform, MutatedTransformPost, DEFAULT_MUTATIONAL_MAX_ITERATIONS},
|
mutational::{MutatedTransform, MutatedTransformPost, DEFAULT_MUTATIONAL_MAX_ITERATIONS},
|
||||||
ExecutionCountRestartHelper, MutationalStage, Stage,
|
ExecutionCountRestartHelper, MutationalStage, Stage,
|
||||||
@ -250,7 +251,7 @@ where
|
|||||||
// fall back to random
|
// fall back to random
|
||||||
1 + state
|
1 + state
|
||||||
.rand_mut()
|
.rand_mut()
|
||||||
.below(NonZero::new(DEFAULT_MUTATIONAL_MAX_ITERATIONS).unwrap()),
|
.below(nonzero!(DEFAULT_MUTATIONAL_MAX_ITERATIONS)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,6 +1050,46 @@ pub unsafe fn set_error_print_panic_hook(new_stderr: RawFd) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Credit goes to https://github.com/thomcc/nonzero_lit
|
||||||
|
// We don't want add another dependency and just want to use usize macro of it.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod _private {
|
||||||
|
pub use core::num::NonZeroUsize;
|
||||||
|
|
||||||
|
macro_rules! define_nz_ctor {
|
||||||
|
($(pub fn $nz_func:ident($n:ident : $int:ident) -> $NonZeroInt:ident;)+) => {$(
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn $nz_func($n : $int) -> $NonZeroInt {
|
||||||
|
// Note: Hacky const fn assert.
|
||||||
|
let _ = ["N must not be zero"][($n == 0) as usize];
|
||||||
|
|
||||||
|
match $NonZeroInt::new($n) {
|
||||||
|
Some(x) => x,
|
||||||
|
// The assert above makes this branch unreachable
|
||||||
|
None => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+};
|
||||||
|
}
|
||||||
|
|
||||||
|
define_nz_ctor! {
|
||||||
|
pub fn nz_usize(n: usize) -> NonZeroUsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 0 cost way to create check nonzero on compilation.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! nonzero {
|
||||||
|
($val:expr $(,)?) => {{
|
||||||
|
const __E: usize = $val;
|
||||||
|
{
|
||||||
|
const NZ: $crate::_private::NonZeroUsize = $crate::_private::nz_usize(__E);
|
||||||
|
NZ
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub mod pybind {
|
pub mod pybind {
|
||||||
|
@ -96,6 +96,13 @@ pub fn fast_bound(rand: u64, n: NonZeroUsize) -> usize {
|
|||||||
(mul >> 64) as usize
|
(mul >> 64) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
fn fast_bound_usize(rand: u64, n: usize) -> usize {
|
||||||
|
let mul = u128::from(rand).wrapping_mul(u128::from(n as u64));
|
||||||
|
(mul >> 64) as usize
|
||||||
|
}
|
||||||
|
|
||||||
/// Ways to get random around here.
|
/// Ways to get random around here.
|
||||||
/// Please note that these are not cryptographically secure.
|
/// Please note that these are not cryptographically secure.
|
||||||
/// Or, even if some might be by accident, at least they are not seeded in a cryptographically secure fashion.
|
/// Or, even if some might be by accident, at least they are not seeded in a cryptographically secure fashion.
|
||||||
@ -130,14 +137,9 @@ pub trait Rand: Debug + Serialize + DeserializeOwned {
|
|||||||
fast_bound(self.next(), upper_bound_excl)
|
fast_bound(self.next(), upper_bound_excl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value below the given bound (inclusive)
|
/// Gets a value between [0, n]
|
||||||
#[inline]
|
fn zero_upto(&mut self, n: usize) -> usize {
|
||||||
fn below_incl(&mut self, upper_bound_incl: usize) -> usize {
|
fast_bound_usize(self.next(), n)
|
||||||
let Some(upper_bound) = NonZero::new(upper_bound_incl.wrapping_add(1)) else {
|
|
||||||
// The max value + 1 wrapped around to 0. We just do a "normal" random.
|
|
||||||
return self.next() as usize;
|
|
||||||
};
|
|
||||||
self.below(upper_bound)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
|
/// Gets a value between the given lower bound (inclusive) and upper bound (inclusive)
|
||||||
@ -548,17 +550,18 @@ impl XkcdRand {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::num::NonZero;
|
use crate::{
|
||||||
|
nonzero,
|
||||||
use crate::rands::{
|
rands::{
|
||||||
Rand, RomuDuoJrRand, RomuTrioRand, Sfc64Rand, StdRand, XorShift64Rand,
|
Rand, RomuDuoJrRand, RomuTrioRand, Sfc64Rand, StdRand, XorShift64Rand,
|
||||||
Xoshiro256PlusPlusRand,
|
Xoshiro256PlusPlusRand,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test_single_rand<R: Rand>(rand: &mut R) {
|
fn test_single_rand<R: Rand>(rand: &mut R) {
|
||||||
assert_ne!(rand.next(), rand.next());
|
assert_ne!(rand.next(), rand.next());
|
||||||
assert!(rand.below(NonZero::new(100).unwrap()) < 100);
|
assert!(rand.below(nonzero!(100)) < 100);
|
||||||
assert_eq!(rand.below(NonZero::new(1).unwrap()), 0);
|
assert_eq!(rand.below(nonzero!(1)), 0);
|
||||||
assert_eq!(rand.between(10, 10), 10);
|
assert_eq!(rand.between(10, 10), 10);
|
||||||
assert!(rand.between(11, 20) > 10);
|
assert!(rand.between(11, 20) > 10);
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,8 @@ pub mod executor;
|
|||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
// for parsing asan and cmplog cores
|
// for parsing asan and cmplog cores
|
||||||
use libafl_bolts::core_affinity::{get_core_ids, CoreId, Cores};
|
|
||||||
|
|
||||||
|
use libafl_bolts::core_affinity::{get_core_ids, CoreId, Cores};
|
||||||
/// A representation of the various Frida options
|
/// A representation of the various Frida options
|
||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
@ -326,6 +326,7 @@ impl Default for FridaOptions {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use core::num::NonZero;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@ -504,8 +505,10 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mutator = StdScheduledMutator::new(tuple_list!(BitFlipMutator::new()));
|
let mutator = StdScheduledMutator::new(tuple_list!(BitFlipMutator::new()));
|
||||||
let mut stages =
|
let mut stages = tuple_list!(StdMutationalStage::with_max_iterations(
|
||||||
tuple_list!(StdMutationalStage::with_max_iterations(mutator, 1).unwrap());
|
mutator,
|
||||||
|
NonZero::new(1).unwrap()
|
||||||
|
));
|
||||||
|
|
||||||
log::info!("Starting fuzzing!");
|
log::info!("Starting fuzzing!");
|
||||||
fuzzer
|
fuzzer
|
||||||
|
@ -170,9 +170,10 @@ macro_rules! fuzz_with {
|
|||||||
StdFuzzer,
|
StdFuzzer,
|
||||||
};
|
};
|
||||||
use libafl_targets::{CmpLogObserver, LLVMCustomMutator, OomFeedback, OomObserver, CMP_MAP};
|
use libafl_targets::{CmpLogObserver, LLVMCustomMutator, OomFeedback, OomObserver, CMP_MAP};
|
||||||
|
use libafl_bolts::nonzero;
|
||||||
use rand::{thread_rng, RngCore};
|
use rand::{thread_rng, RngCore};
|
||||||
use std::{env::temp_dir, fs::create_dir, path::PathBuf};
|
use std::{env::temp_dir, fs::create_dir, path::PathBuf};
|
||||||
|
use core::num::NonZeroUsize;
|
||||||
use crate::{
|
use crate::{
|
||||||
CustomMutationStatus,
|
CustomMutationStatus,
|
||||||
corpus::{ArtifactCorpus, LibfuzzerCorpus},
|
corpus::{ArtifactCorpus, LibfuzzerCorpus},
|
||||||
@ -375,7 +376,7 @@ macro_rules! fuzz_with {
|
|||||||
LLVMCustomMutator::mutate_unchecked(StdScheduledMutator::new(havoc_mutations_no_crossover().merge(tokens_mutations())))
|
LLVMCustomMutator::mutate_unchecked(StdScheduledMutator::new(havoc_mutations_no_crossover().merge(tokens_mutations())))
|
||||||
};
|
};
|
||||||
// Safe to unwrap: stack pow is not 0.
|
// Safe to unwrap: stack pow is not 0.
|
||||||
let std_mutator_no_mutate = StdScheduledMutator::with_max_stack_pow(havoc_crossover(), 3).unwrap();
|
let std_mutator_no_mutate = StdScheduledMutator::with_max_stack_pow(havoc_crossover(),3);
|
||||||
|
|
||||||
let cm_power: StdPowerMutationalStage<_, _, BytesInput, _, _> = StdPowerMutationalStage::new(custom_mutator);
|
let cm_power: StdPowerMutationalStage<_, _, BytesInput, _, _> = StdPowerMutationalStage::new(custom_mutator);
|
||||||
let cm_power = IfStage::new(|_, _, _, _| Ok(mutator_status.custom_mutation.into()), (cm_power, ()));
|
let cm_power = IfStage::new(|_, _, _, _| Ok(mutator_status.custom_mutation.into()), (cm_power, ()));
|
||||||
@ -391,7 +392,7 @@ macro_rules! fuzz_with {
|
|||||||
LLVMCustomMutator::crossover_unchecked(StdScheduledMutator::with_max_stack_pow(
|
LLVMCustomMutator::crossover_unchecked(StdScheduledMutator::with_max_stack_pow(
|
||||||
havoc_mutations_no_crossover().merge(tokens_mutations()),
|
havoc_mutations_no_crossover().merge(tokens_mutations()),
|
||||||
3,
|
3,
|
||||||
).unwrap())
|
))
|
||||||
};
|
};
|
||||||
let std_mutator_no_crossover = StdScheduledMutator::new(havoc_mutations_no_crossover().merge(tokens_mutations()));
|
let std_mutator_no_crossover = StdScheduledMutator::new(havoc_mutations_no_crossover().merge(tokens_mutations()));
|
||||||
|
|
||||||
@ -412,7 +413,7 @@ macro_rules! fuzz_with {
|
|||||||
GrimoireRandomDeleteMutator::new(),
|
GrimoireRandomDeleteMutator::new(),
|
||||||
),
|
),
|
||||||
3,
|
3,
|
||||||
).unwrap();
|
);
|
||||||
let grimoire = IfStage::new(|_, _, _, _| Ok(grimoire.into()), (StdMutationalStage::transforming(grimoire_mutator), ()));
|
let grimoire = IfStage::new(|_, _, _, _| Ok(grimoire.into()), (StdMutationalStage::transforming(grimoire_mutator), ()));
|
||||||
|
|
||||||
// A minimization+queue policy to get testcasess from the corpus
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
@ -467,7 +468,7 @@ macro_rules! fuzz_with {
|
|||||||
}
|
}
|
||||||
if state.corpus().count() < 1 {
|
if state.corpus().count() < 1 {
|
||||||
// Generator of bytearrays of max size 64
|
// Generator of bytearrays of max size 64
|
||||||
let mut generator = RandBytesGenerator::from(RandBytesGenerator::new(64).unwrap());
|
let mut generator = RandBytesGenerator::from(RandBytesGenerator::new(nonzero!(64)));
|
||||||
|
|
||||||
// Generate 1024 initial inputs
|
// Generate 1024 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -24,6 +24,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::Cores,
|
core_affinity::Cores,
|
||||||
|
nonzero,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
|
shmem::{ShMem, ShMemProvider, UnixShMemProvider},
|
||||||
tuples::{tuple_list, Handled, Merge},
|
tuples::{tuple_list, Handled, Merge},
|
||||||
@ -213,7 +214,7 @@ impl ForkserverBytesCoverageSugar<'_> {
|
|||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
if self.input_dirs.is_empty() {
|
if self.input_dirs.is_empty() {
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandBytesGenerator::new(32).unwrap();
|
let mut generator = RandBytesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -27,6 +27,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::Cores,
|
core_affinity::Cores,
|
||||||
|
nonzero,
|
||||||
ownedref::OwnedMutSlice,
|
ownedref::OwnedMutSlice,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
@ -229,7 +230,7 @@ where
|
|||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
if self.input_dirs.is_empty() {
|
if self.input_dirs.is_empty() {
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandBytesGenerator::new(32).unwrap();
|
let mut generator = RandBytesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
@ -30,6 +30,7 @@ use libafl::{
|
|||||||
};
|
};
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::Cores,
|
core_affinity::Cores,
|
||||||
|
nonzero,
|
||||||
ownedref::OwnedMutSlice,
|
ownedref::OwnedMutSlice,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
@ -259,7 +260,7 @@ where
|
|||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
if self.input_dirs.is_empty() {
|
if self.input_dirs.is_empty() {
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandBytesGenerator::new(32).unwrap();
|
let mut generator = RandBytesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
@ -375,7 +376,7 @@ where
|
|||||||
if state.must_load_initial_inputs() {
|
if state.must_load_initial_inputs() {
|
||||||
if self.input_dirs.is_empty() {
|
if self.input_dirs.is_empty() {
|
||||||
// Generator of printable bytearrays of max size 32
|
// Generator of printable bytearrays of max size 32
|
||||||
let mut generator = RandBytesGenerator::new(32).unwrap();
|
let mut generator = RandBytesGenerator::new(nonzero!(32));
|
||||||
|
|
||||||
// Generate 8 initial inputs
|
// Generate 8 initial inputs
|
||||||
state
|
state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user