diff --git a/.gitignore b/.gitignore index 3987d09d2ca..9aeadb2e5e8 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,36 @@ codegen mutants.out mutants.out.old + + +# TODO: remove unused +tooling/nargo_cli/counter.txt +tooling/nargo_cli/kill_tests_if_out_of_space.rb.* +tooling/nargo_fuzz_target/*inputs +tooling/nargo_fuzz_target/collected_outputs/ +tooling/nargo_fuzz_target/outputs* +tooling/nargo_fuzz_target/tmp/ +tooling/nargo_fuzz_target/unique_crashes/ +tooling/ssa_afl_fuzzer/collected_outputs/ +tooling/ssa_afl_fuzzer/combined_inputs/ +tooling/ssa_afl_fuzzer/defunctionalize_inputs/ +tooling/ssa_afl_fuzzer/fuzzer*.log +tooling/ssa_afl_fuzzer/inline_simple_inputs/ +tooling/ssa_afl_fuzzer/outputs/ +tooling/ssa_afl_fuzzer/outputs2/ +tooling/ssa_afl_fuzzer/outputs3/ +tooling/ssa_afl_fuzzer/outputs4/ +tooling/ssa_afl_fuzzer/outputs5/ +tooling/ssa_afl_fuzzer/outputs6/ +tooling/ssa_afl_fuzzer/outputs7/ +tooling/ssa_afl_fuzzer/outputs8/ +tooling/ssa_afl_fuzzer/remove_unreachable_functions_inputs/ +tooling/ssa_afl_fuzzer/screen_sessions_at_fuzzer01_etc +tooling/ssa_afl_fuzzer/tt.txt +tooling/ssa_afl_fuzzer/unique_crash_location_representatives/ +tooling/ssa_afl_fuzzer/unique_crashes/ +tooling/ssa_fuzzer/crash0.log +tooling/ssa_fuzzer/crash1.log +tooling/ssa_fuzzer/fuzz-*.log +tooling/ssa_fuzzer/nohup.out +tooling/unique_crashes diff --git a/Cargo.lock b/Cargo.lock index c7ec55f08be..b1999af0845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3733,6 +3733,7 @@ dependencies = [ "serde_with", "similar-asserts", "smallvec", + "stacker", "test-case", "thiserror 1.0.69", "tracing", @@ -4481,6 +4482,15 @@ dependencies = [ "zip", ] +[[package]] +name = "psm" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" +dependencies = [ + "cc", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -5431,6 +5441,14 @@ dependencies = [ "der", ] +[[package]] +name = "ssa_afl_fuzzer" +version = "1.0.0-beta.4" +dependencies = [ + "afl", + "noirc_evaluator", +] + [[package]] name = "ssa_fuzzer_fuzz" version = "0.0.1" @@ -5450,6 +5468,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stacker" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index a5f644a024c..5e6f9171a83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ members = [ "tooling/ssa_fuzzer", "tooling/ssa_fuzzer/fuzzer", + "tooling/ssa_afl_fuzzer", # cargo-afl fuzzer "utils/protobuf", ] default-members = [ diff --git a/compiler/noirc_evaluator/Cargo.toml b/compiler/noirc_evaluator/Cargo.toml index 2463858c50d..f7fce7ac79f 100644 --- a/compiler/noirc_evaluator/Cargo.toml +++ b/compiler/noirc_evaluator/Cargo.toml @@ -34,6 +34,7 @@ cfg-if.workspace = true smallvec = { version = "1.13.2", features = ["serde"] } vec-collections = "0.4.3" petgraph.workspace = true +stacker = "0.1.21" [dev-dependencies] proptest.workspace = true diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index dace609f04a..c18d0176951 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -47,8 +47,11 @@ pub mod function_builder; pub mod interpreter; pub mod ir; pub(crate) mod opt; -#[cfg(test)] -pub(crate) mod parser; + +// TODO: only for testing? +// #[cfg(test)] +// pub(crate) mod parser; +pub mod parser; pub mod ssa_gen; #[derive(Debug, Clone)] @@ -710,6 +713,9 @@ impl SsaBuilder { } fn print(mut self, msg: &str) -> Self { + // // TODO: disable this always-print option + // self.ssa_logging = SsaLogging::All; + // Always normalize if we are going to print at least one of the passes if !matches!(self.ssa_logging, SsaLogging::None) { self.ssa.normalize_ids(); @@ -729,6 +735,26 @@ impl SsaBuilder { if print_ssa_pass { println!("After {msg}:\n{}", self.ssa); } + + // TODO: BEGIN: quick hack for audit + let counter_path = Path::new("./counter.txt"); + // make counter file if missing + if !counter_path.is_file() { + std::fs::write(counter_path, 0u64.to_string()).expect("Unable to write counter file"); + } + // read counter from file + let mut counter: u64 = std::fs::read_to_string(counter_path).expect("Unable to read counter file").parse().unwrap(); + + // write to input_[counter].ssa + let output_file = PathBuf::from(format!("./input_{counter}.ssa")); + std::fs::write(output_file, format!("{}", self.ssa)).expect("Unable to write output file"); + + // update counter in file + counter += 1; + let counter_str = counter.to_string(); + std::fs::write(counter_path, counter_str).expect("Unable to write counter file"); + // TODO: END: quick hack for audit + self } } diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index 00c1311eb30..f786216d38e 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -363,7 +363,8 @@ impl FunctionBuilder { .first() } - #[cfg(test)] + // TODO: used in fuzzing too + // #[cfg(test)] pub fn insert_mutable_array_set( &mut self, array: ValueId, @@ -395,7 +396,12 @@ impl FunctionBuilder { /// Insert a `make_array` instruction to create a new array or slice. /// Returns the new array value. Expects `typ` to be an array or slice type. pub fn insert_make_array(&mut self, elements: im::Vector, typ: Type) -> ValueId { - assert!(matches!(typ, Type::Array(..) | Type::Slice(_))); + + // TODO: re-enable + if !matches!(typ, Type::Array(..) | Type::Slice(_)) { + std::process::exit(0); + } + // assert!(matches!(typ, Type::Array(..) | Type::Slice(_))); self.insert_instruction(Instruction::MakeArray { elements, typ }, None).first() } @@ -551,17 +557,21 @@ fn validate_numeric_type(typ: &NumericType) { NumericType::Signed { bit_size } => match bit_size { 8 | 16 | 32 | 64 => (), _ => { - panic!( - "Invalid bit size for signed numeric type: {bit_size}. Expected one of 8, 16, 32 or 64." - ); + // TODO: re-enable + std::process::exit(0); + // panic!( + // "Invalid bit size for signed numeric type: {bit_size}. Expected one of 8, 16, 32 or 64." + // ); } }, NumericType::Unsigned { bit_size } => match bit_size { 1 | 8 | 16 | 32 | 64 | 128 => (), _ => { - panic!( - "Invalid bit size for unsigned numeric type: {bit_size}. Expected one of 1, 8, 16, 32, 64, or 128." - ); + // TODO: re-enable + std::process::exit(0); + // panic!( + // "Invalid bit size for unsigned numeric type: {bit_size}. Expected one of 1, 8, 16, 32, 64, or 128." + // ); } }, _ => (), diff --git a/compiler/noirc_evaluator/src/ssa/interpreter/errors.rs b/compiler/noirc_evaluator/src/ssa/interpreter/errors.rs index f0789dc1dc1..2ca255b68a7 100644 --- a/compiler/noirc_evaluator/src/ssa/interpreter/errors.rs +++ b/compiler/noirc_evaluator/src/ssa/interpreter/errors.rs @@ -10,7 +10,7 @@ pub(super) const MAX_SIGNED_BIT_SIZE: u32 = 64; pub(super) const MAX_UNSIGNED_BIT_SIZE: u32 = 128; #[derive(Debug, Error)] -pub(crate) enum InterpreterError { +pub enum InterpreterError { /// These errors are all the result from malformed input SSA #[error("{0}")] Internal(InternalError), @@ -60,7 +60,7 @@ pub(crate) enum InterpreterError { /// These errors can only result from interpreting malformed SSA #[derive(Debug, Error)] -pub(crate) enum InternalError { +pub enum InternalError { #[error( "Argument count {arguments} to block {block} does not match the expected parameter count {parameters}" )] diff --git a/compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs b/compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs index b836e7c71af..367715b5031 100644 --- a/compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs +++ b/compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs @@ -64,7 +64,9 @@ impl Interpreter<'_> { Intrinsic::SliceInsert => self.slice_insert(args), Intrinsic::SliceRemove => self.slice_remove(args), Intrinsic::ApplyRangeConstraint => { - todo!("Intrinsic::ApplyRangeConstraint is currently unimplemented") + // TODO + // todo!("Intrinsic::ApplyRangeConstraint is currently unimplemented") + std::process::exit(0) } // Both of these are no-ops Intrinsic::StrAsBytes | Intrinsic::AsWitness => { @@ -82,16 +84,26 @@ impl Interpreter<'_> { let radix = self.lookup_u32(args[1], "call to to_bits")?; self.to_radix(endian, args[0], field, radix, results[0]) } - Intrinsic::BlackBox(black_box_func) => { - todo!("Intrinsic::BlackBox({black_box_func}) is currently unimplemented") + // TODO + // Intrinsic::BlackBox(black_box_func) => { + Intrinsic::BlackBox(_black_box_func) => { + // TODO + // todo!("Intrinsic::BlackBox({black_box_func}) is currently unimplemented") + std::process::exit(0) + } + Intrinsic::Hint(_) => { + // TODO + // todo!("Intrinsic::Hint is currently unimplemented") + std::process::exit(0) } - Intrinsic::Hint(_) => todo!("Intrinsic::Hint is currently unimplemented"), Intrinsic::IsUnconstrained => { check_argument_count(args, 0, intrinsic)?; Ok(vec![Value::bool(self.in_unconstrained_context())]) } Intrinsic::DerivePedersenGenerators => { - todo!("Intrinsic::DerivePedersenGenerators is currently unimplemented") + // TODO + // todo!("Intrinsic::DerivePedersenGenerators is currently unimplemented") + std::process::exit(0) } Intrinsic::FieldLessThan => { if !self.in_unconstrained_context() { diff --git a/compiler/noirc_evaluator/src/ssa/interpreter/mod.rs b/compiler/noirc_evaluator/src/ssa/interpreter/mod.rs index 94ee799dac3..7d141bda490 100644 --- a/compiler/noirc_evaluator/src/ssa/interpreter/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/interpreter/mod.rs @@ -63,7 +63,7 @@ type IResults = IResult>; #[allow(unused)] impl Ssa { - pub(crate) fn interpret(&self, args: Vec) -> IResults { + pub fn interpret(&self, args: Vec) -> IResults { self.interpret_function(self.main_id, args) } @@ -223,7 +223,9 @@ impl<'ssa> Interpreter<'ssa> { super::ir::value::Value::Instruction { .. } | super::ir::value::Value::Param { .. } | super::ir::value::Value::Global(_) => { - unreachable!("`{id}` should already be in scope") + // TODO + // unreachable!("`{id}` should already be in scope") + std::process::exit(0) } } } @@ -653,7 +655,9 @@ impl<'ssa> Interpreter<'ssa> { let element = if self.side_effects_enabled() { let array = self.lookup_array_or_slice(array, "array get")?; let index = self.lookup_u32(index, "array get index")?; - array.elements.borrow()[index as usize].clone() + // TODO: error for index out of bounds + // array.elements.borrow()[index as usize].clone() + array.elements.borrow().get(index as usize).unwrap_or_else(|| { std::process::exit(0) }).clone() } else { let typ = self.dfg().type_of_value(result); Value::uninitialized(&typ, result) @@ -680,11 +684,15 @@ impl<'ssa> Interpreter<'ssa> { if self.in_unconstrained_context() { *array.rc.borrow() == 1 } else { mutable }; if should_mutate { - array.elements.borrow_mut()[index as usize] = value; + // TODO: error for index out of bounds + // array.elements.borrow_mut()[index as usize] = value; + array.elements.borrow_mut().get_mut(index as usize).map(|element| *element = value).unwrap_or_else(|| { std::process::exit(0) }); Value::ArrayOrSlice(array.clone()) } else { let mut elements = array.elements.borrow().to_vec(); - elements[index as usize] = value; + // TODO: error for index out of bounds + // elements[index as usize] = value; + elements.get_mut(index as usize).map(|element| *element = value).unwrap_or_else(|| { std::process::exit(0) }); let elements = Shared::new(elements); let rc = Shared::new(1); let element_types = array.element_types.clone(); @@ -1124,7 +1132,7 @@ where { let value_u128 = u128::from(value); let bit_mask = match bit_size.cmp(&MAX_UNSIGNED_BIT_SIZE) { - Ordering::Less => (1u128 << bit_size) - 1, + Ordering::Less => (1u128.checked_shl(bit_size).unwrap_or_else(|| { std::process::exit(0) })) - 1, Ordering::Equal => u128::MAX, Ordering::Greater => { return Err(internal(InternalError::InvalidUnsignedTruncateBitSize { bit_size })); @@ -1145,13 +1153,15 @@ where { let mut value_i128 = i128::from(value); if value_i128 < 0 { - let max = 1i128 << (bit_size - 1); - value_i128 += max; if bit_size > MAX_SIGNED_BIT_SIZE { - return Err(internal(InternalError::InvalidSignedTruncateBitSize { bit_size })); + // TODO: this check needs to be before the '<<' + // return Err(internal(InternalError::InvalidSignedTruncateBitSize { bit_size })); + std::process::exit(0) } + let max = 1i128.checked_shl(bit_size - 1).unwrap_or_else(|| { std::process::exit(0) }); + value_i128 += max; - let mask = (1i128 << bit_size) - 1; + let mask = (1i128.checked_shl(bit_size).unwrap_or_else(|| { std::process::exit(0) })) - 1; let result = (value_i128 & mask) - max; Ok(T::try_from(result).expect( diff --git a/compiler/noirc_evaluator/src/ssa/interpreter/value.rs b/compiler/noirc_evaluator/src/ssa/interpreter/value.rs index bafe384c10b..73633dcaa73 100644 --- a/compiler/noirc_evaluator/src/ssa/interpreter/value.rs +++ b/compiler/noirc_evaluator/src/ssa/interpreter/value.rs @@ -12,7 +12,7 @@ use crate::ssa::ir::{ }; #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum Value { +pub enum Value { Numeric(NumericValue), Reference(ReferenceValue), ArrayOrSlice(ArrayValue), @@ -22,7 +22,7 @@ pub(crate) enum Value { } #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub(crate) enum NumericValue { +pub enum NumericValue { Field(FieldElement), U1(bool), @@ -39,7 +39,7 @@ pub(crate) enum NumericValue { } #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct ReferenceValue { +pub struct ReferenceValue { /// This is included mostly for debugging to distinguish different /// ReferenceValues which store the same element. pub original_id: ValueId, @@ -51,7 +51,7 @@ pub(crate) struct ReferenceValue { } #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) struct ArrayValue { +pub struct ArrayValue { pub elements: Shared>, /// The `Shared` type contains its own reference count but we need to track @@ -157,7 +157,9 @@ impl Value { /// value but we make no guarantee that it is. This is often used as the default /// value to return for side-effectful functions like `call` or `array_get` when /// side-effects are disabled. - pub(crate) fn uninitialized(typ: &Type, id: ValueId) -> Value { + // TODO: revert + // pub(crate) fn uninitialized(typ: &Type, id: ValueId) -> Value { + pub fn uninitialized(typ: &Type, id: ValueId) -> Value { match typ { Type::Numeric(typ) => Value::Numeric(NumericValue::zero(*typ)), Type::Reference(element_type) => Self::reference(id, element_type.clone()), @@ -231,34 +233,64 @@ impl NumericValue { match typ { NumericType::NativeField => Self::Field(constant), NumericType::Unsigned { bit_size: 1 } => Self::U1(constant.is_one()), + // TODO: re-enable unwrap's + // NumericType::Unsigned { bit_size: 8 } => { + // Self::U8(constant.try_into_u128().unwrap().try_into().unwrap()) + // } + // NumericType::Unsigned { bit_size: 16 } => { + // Self::U16(constant.try_into_u128().unwrap().try_into().unwrap()) + // } + // NumericType::Unsigned { bit_size: 32 } => { + // Self::U32(constant.try_into_u128().unwrap().try_into().unwrap()) + // } + // NumericType::Unsigned { bit_size: 64 } => { + // Self::U64(constant.try_into_u128().unwrap().try_into().unwrap()) + // } + // NumericType::Unsigned { bit_size: 128 } => { + // Self::U128(constant.try_into_u128().unwrap()) + // } + // NumericType::Signed { bit_size: 8 } => { + // Self::I8(constant.try_into_i128().unwrap().try_into().unwrap()) + // } + // NumericType::Signed { bit_size: 16 } => { + // Self::I16(constant.try_into_i128().unwrap().try_into().unwrap()) + // } + // NumericType::Signed { bit_size: 32 } => { + // Self::I32(constant.try_into_i128().unwrap().try_into().unwrap()) + // } + // NumericType::Signed { bit_size: 64 } => { + // Self::I64(constant.try_into_i128().unwrap().try_into().unwrap()) + // } NumericType::Unsigned { bit_size: 8 } => { - Self::U8(constant.try_into_u128().unwrap().try_into().unwrap()) + Self::U8(constant.try_into_u128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Unsigned { bit_size: 16 } => { - Self::U16(constant.try_into_u128().unwrap().try_into().unwrap()) + Self::U16(constant.try_into_u128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Unsigned { bit_size: 32 } => { - Self::U32(constant.try_into_u128().unwrap().try_into().unwrap()) + Self::U32(constant.try_into_u128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Unsigned { bit_size: 64 } => { - Self::U64(constant.try_into_u128().unwrap().try_into().unwrap()) + Self::U64(constant.try_into_u128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Unsigned { bit_size: 128 } => { - Self::U128(constant.try_into_u128().unwrap()) + Self::U128(constant.try_into_u128().unwrap_or_else(|| { std::process::exit(0) })) } NumericType::Signed { bit_size: 8 } => { - Self::I8(constant.try_into_i128().unwrap().try_into().unwrap()) + Self::I8(constant.try_into_i128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Signed { bit_size: 16 } => { - Self::I16(constant.try_into_i128().unwrap().try_into().unwrap()) + Self::I16(constant.try_into_i128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Signed { bit_size: 32 } => { - Self::I32(constant.try_into_i128().unwrap().try_into().unwrap()) + Self::I32(constant.try_into_i128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } NumericType::Signed { bit_size: 64 } => { - Self::I64(constant.try_into_i128().unwrap().try_into().unwrap()) + Self::I64(constant.try_into_i128().unwrap_or_else(|| { std::process::exit(0) }).try_into().unwrap_or_else(|_| { std::process::exit(0) })) } - other => panic!("Unsupported numeric type: {other}"), + // TODO: re-enable + // other => panic!("Unsupported numeric type: {other}"), + _other => std::process::exit(0), } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/basic_block.rs b/compiler/noirc_evaluator/src/ssa/ir/basic_block.rs index 1bfe454ecae..d57684de1ad 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/basic_block.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/basic_block.rs @@ -100,14 +100,18 @@ impl BasicBlock { /// /// Once this block has finished construction, this is expected to always be Some. pub(crate) fn unwrap_terminator(&self) -> &TerminatorInstruction { - self.terminator().expect("Expected block to have terminator instruction") + // TODO: re-enable + // self.terminator().expect("Expected block to have terminator instruction") + self.terminator().unwrap_or_else(|| { std::process::exit(0) }) } /// Returns a mutable reference to the terminator of this block. /// /// Once this block has finished construction, this is expected to always be Some. pub(crate) fn unwrap_terminator_mut(&mut self) -> &mut TerminatorInstruction { - self.terminator.as_mut().expect("Expected block to have terminator instruction") + // TODO: re-enable + // self.terminator.as_mut().expect("Expected block to have terminator instruction") + self.terminator.as_mut().unwrap_or_else(|| { std::process::exit(0) }) } /// Take ownership of this block's terminator, replacing it with an empty return terminator @@ -118,7 +122,9 @@ impl BasicBlock { /// block without setting the terminator afterward will result in the empty return terminator /// being kept, which is likely unwanted. pub(crate) fn take_terminator(&mut self) -> TerminatorInstruction { - let terminator = self.terminator.as_mut().expect("Expected block to have a terminator"); + // TODO: re-enable + // let terminator = self.terminator.as_mut().expect("Expected block to have a terminator"); + let terminator = self.terminator.as_mut().unwrap_or_else(|| { std::process::exit(0) }); std::mem::replace( terminator, TerminatorInstruction::Return { diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index a0af3979271..cd4069fff6b 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -264,7 +264,9 @@ impl DataFlowGraph { if !self.is_handled_by_runtime(&instruction) { // Panicking to raise attention. If we're not supposed to simplify it immediately, // pushing the instruction would just cause a potential panic later on. - panic!("Attempted to insert instruction not handled by runtime: {instruction:?}"); + // TODO + // panic!("Attempted to insert instruction not handled by runtime: {instruction:?}"); + std::process::exit(0) } let id = self.insert_instruction_without_simplification( instruction, @@ -527,7 +529,9 @@ impl DataFlowGraph { /// Returns the type of a given value pub(crate) fn type_of_value(&self, value: ValueId) -> Type { - self.values[value].get_type().into_owned() + // TODO: re-enable + // self.values[value].get_type().into_owned() + self.values.get(value).unwrap_or_else(|| { std::process::exit(0) }).get_type().into_owned() } /// Returns the maximum possible number of bits that `value` can potentially be. @@ -747,7 +751,9 @@ impl DataFlowGraph { } pub(crate) fn is_global(&self, value: ValueId) -> bool { - matches!(self.values[value], Value::Global(_)) + // TODO + // matches!(self.values[value], Value::Global(_)) + matches!(self.values.get(value).unwrap_or_else(|| { std::process::exit(0) }), Value::Global(_)) } /// Uses value information to determine whether an instruction is from diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs index d8aed40f702..d9793b3feed 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs @@ -121,8 +121,10 @@ pub(crate) fn simplify( let array = dfg.get_array_constant(*array_id); let index = dfg.get_numeric_constant(*index_id); if let (Some((array, _element_type)), Some(index)) = (array, index) { + // TODO + // index.try_to_u32().expect("Expected array index to fit in u32") as usize; let index = - index.try_to_u32().expect("Expected array index to fit in u32") as usize; + index.try_to_u32().unwrap_or_else(|| { std::process::exit(0) }) as usize; if index < array.len() { let elements = array.update(index, *value); diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs index 137ce6964c7..d0c2a3f2583 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs @@ -21,7 +21,9 @@ pub(super) fn simplify_binary(binary: &Binary, dfg: &mut DataFlowGraph) -> Simpl let operator = binary.operator; if operator != BinaryOp::Shl && operator != BinaryOp::Shr { - assert_eq!(lhs_type, rhs_type, "ICE - Binary instruction operands must have the same type"); + // TODO + // assert_eq!(lhs_type, rhs_type, "ICE - Binary instruction operands must have the same type"); + std::process::exit(0) } let operator = if lhs_type == NumericType::NativeField { diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/call.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/call.rs index 27b7a04422e..f539b89509e 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/call.rs @@ -73,6 +73,10 @@ pub(super) fn simplify_call( Intrinsic::ToRadix(endian) => { // TODO: simplify to a range constraint if `limb_count == 1` if let (Some(constant_args), Some(return_type)) = (constant_args, return_type.clone()) { + // TODO + if constant_args.len() < 2 { + std::process::exit(0) + } let field = constant_args[0]; let radix = constant_args[1].to_u128() as u32; let limb_count = if let Type::Array(_, array_len) = return_type { diff --git a/compiler/noirc_evaluator/src/ssa/ir/function.rs b/compiler/noirc_evaluator/src/ssa/ir/function.rs index cc4653fd0ca..fccfed33097 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/function.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/function.rs @@ -159,7 +159,9 @@ impl Function { /// Returns the parameters of this function. /// The parameters will always match that of this function's entry block. - pub(crate) fn parameters(&self) -> &[ValueId] { + // TODO: revert + // pub(crate) fn parameters(&self) -> &[ValueId] { + pub fn parameters(&self) -> &[ValueId] { self.dfg.block_parameters(self.entry_block) } @@ -191,7 +193,9 @@ impl Function { blocks } - pub(crate) fn signature(&self) -> Signature { + // TODO revert + // pub(crate) fn signature(&self) -> Signature { + pub fn signature(&self) -> Signature { let params = vecmap(self.parameters(), |param| self.dfg.type_of_value(*param)); let returns = vecmap(self.returns(), |ret| self.dfg.type_of_value(*ret)); Signature { params, returns } @@ -241,8 +245,12 @@ impl std::fmt::Display for RuntimeType { pub(crate) type FunctionId = Id; #[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub(crate) struct Signature { - pub(crate) params: Vec, +// TODO revert +// pub(crate) struct Signature { +pub struct Signature { + // TODO revert + // pub(crate) params: Vec, + pub params: Vec, pub(crate) returns: Vec, } diff --git a/compiler/noirc_evaluator/src/ssa/ir/map.rs b/compiler/noirc_evaluator/src/ssa/ir/map.rs index eee5d760fc1..73f89820906 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/map.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/map.rs @@ -42,7 +42,9 @@ impl Id { /// be used for testing. Obtaining Ids in this way should be avoided /// as unlike DenseMap::push and SparseMap::push, the Ids created /// here are likely invalid for any particularly map. - #[cfg(test)] + + // TODO: used for fuzzing + // #[cfg(test)] pub(crate) fn test_new(index: u32) -> Self { Self::new(index) } @@ -194,6 +196,10 @@ impl DenseMap { let ids_iter = (0..self.storage.len() as u32).map(|idx| Id::new(idx)); ids_iter.zip(self.storage.iter()) } + + pub(crate) fn get(&self, id: Id) -> Option<&T> { + self.storage.get(id.index as usize) + } } impl Default for DenseMap { diff --git a/compiler/noirc_evaluator/src/ssa/ir/types.rs b/compiler/noirc_evaluator/src/ssa/ir/types.rs index 4bc80e8cc82..a4b03ce5b48 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/types.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/types.rs @@ -190,7 +190,9 @@ impl Type { pub(crate) fn unwrap_numeric(&self) -> NumericType { match self { Type::Numeric(numeric) => *numeric, - other => panic!("Expected NumericType, found {other}"), + // TODO + // other => panic!("Expected NumericType, found {other}"), + _other => std::process::exit(0), } } @@ -202,7 +204,9 @@ impl Type { pub(crate) fn bit_size(&self) -> u32 { match self { Type::Numeric(numeric_type) => numeric_type.bit_size(), - other => panic!("bit_size: Expected numeric type, found {other}"), + // TODO + // other => panic!("bit_size: Expected numeric type, found {other}"), + _other => std::process::exit(0), } } @@ -213,7 +217,9 @@ impl Type { pub(crate) fn element_size(&self) -> usize { match self { Type::Array(elements, _) | Type::Slice(elements) => elements.len(), - other => panic!("element_size: Expected array or slice, found {other}"), + // TODO + // other => panic!("element_size: Expected array or slice, found {other}"), + _other => std::process::exit(0), } } @@ -271,7 +277,9 @@ impl Type { pub(crate) fn element_types(self) -> Arc> { match self { Type::Array(element_types, _) | Type::Slice(element_types) => element_types, - other => panic!("element_types: Expected array or slice, found {other}"), + // TODO: re-enable + // other => panic!("element_types: Expected array or slice, found {other}"), + _other => std::process::exit(0), } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index c3e27f6a070..0328e1c65bc 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -89,7 +89,9 @@ struct DefunctionalizationContext { impl Ssa { /// See [`defunctionalize`][self] module for more information. #[tracing::instrument(level = "trace", skip(self))] - pub(crate) fn defunctionalize(mut self) -> Ssa { + // TODO revert? + // pub(crate) fn defunctionalize(mut self) -> Ssa { + pub fn defunctionalize(mut self) -> Ssa { // Find all functions used as value that share the same signature and runtime type let variants = find_variants(&self); @@ -371,10 +373,15 @@ fn find_dynamic_dispatches(func: &Function) -> BTreeSet { fn create_apply_functions(ssa: &mut Ssa, variants_map: Variants) -> ApplyFunctions { let mut apply_functions = HashMap::default(); for ((mut signature, runtime), variants) in variants_map.into_iter() { - assert!( - !variants.is_empty(), - "ICE: at least one variant should exist for a dynamic call {signature:?}" - ); + // TODO: re-enable and remove this "if variants.is_empty.." + if variants.is_empty() { + continue; + } + // assert!( + // !variants.is_empty(), + // "ICE: at least one variant should exist for a dynamic call {signature:?}" + // ); + // let dispatches_to_multiple_functions = variants.len() > 1; // Update the shared function signature of the higher-order function variants @@ -540,6 +547,79 @@ mod tests { use super::Ssa; + #[test] + fn defunctionalize_missing_fn() { + let src = " + brillig(inline) fn main f0 { + + b0(v0: function, v1: u32): + v2 = call v0(v1) -> u32 + return v2 + } + "; + + let ssa = Ssa::from_str(src).unwrap(); + let ssa = ssa.defunctionalize(); + + assert_ssa_snapshot!(ssa, @r" + brillig(inline) fn main f0 { + b0(v0: u32): + v3 = call f1(Field 2, v0) -> u32 + v5 = add v0, u32 1 + v6 = eq v3, v5 + constrain v3 == v5 + v8 = call f1(Field 3, v0) -> u32 + v9 = add v0, u32 1 + v10 = eq v8, v9 + constrain v8 == v9 + v12 = call f1(Field 4, v0) -> u32 + v13 = add v0, u32 1 + constrain v12 == v13 + return + } + brillig(inline) fn wrapper f1 { + b0(v0: Field, v1: u32): + v3 = call f5(v0, v1) -> u32 + return v3 + } + brillig(inline) fn increment f2 { + b0(v0: u32): + v2 = add v0, u32 1 + return v2 + } + brillig(inline) fn increment_acir f3 { + b0(v0: u32): + v2 = add v0, u32 1 + return v2 + } + brillig(inline) fn increment_three f4 { + b0(v0: u32): + v2 = add v0, u32 1 + return v2 + } + brillig(inline_always) fn apply f5 { + b0(v0: Field, v1: u32): + v4 = eq v0, Field 2 + jmpif v4 then: b3, else: b2 + b1(v2: u32): + return v2 + b2(): + v8 = eq v0, Field 3 + jmpif v8 then: b5, else: b4 + b3(): + v6 = call f2(v1) -> u32 + jmp b1(v6) + b4(): + constrain v0 == Field 4 + v13 = call f4(v1) -> u32 + jmp b1(v13) + b5(): + v10 = call f3(v1) -> u32 + jmp b1(v10) + } + "); + } + #[test] fn apply_inherits_caller_runtime() { // Extracted from `execution_success/brillig_fns_as_values` with `--force-brillig` diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs index 0427b5ea78d..a9741a68a14 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/value_merger.rs @@ -82,10 +82,14 @@ impl<'a> ValueMerger<'a> { ) -> ValueId { let then_type = dfg.type_of_value(then_value).unwrap_numeric(); let else_type = dfg.type_of_value(else_value).unwrap_numeric(); - assert_eq!( - then_type, else_type, - "Expected values merged to be of the same type but found {then_type} and {else_type}" - ); + // TODO: re-enable after using to show fuzzer what inputs are valid + // assert_eq!( + // then_type, else_type, + // "Expected values merged to be of the same type but found {then_type} and {else_type}" + // ); + if then_type != else_type { + std::process::exit(0) + } if then_value == else_value { return then_value; diff --git a/compiler/noirc_evaluator/src/ssa/opt/inline_functions_with_at_most_one_instruction.rs b/compiler/noirc_evaluator/src/ssa/opt/inline_functions_with_at_most_one_instruction.rs index 9b96c10c85b..fe52e5ead76 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inline_functions_with_at_most_one_instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inline_functions_with_at_most_one_instruction.rs @@ -14,7 +14,9 @@ use crate::ssa::{ impl Ssa { /// See the [`inline_functions_with_at_most_one_instruction`][self] module for more information. - pub(crate) fn inline_functions_with_at_most_one_instruction(mut self: Ssa) -> Ssa { + // TODO: revert + // pub(crate) fn inline_functions_with_at_most_one_instruction(mut self: Ssa) -> Ssa { + pub fn inline_functions_with_at_most_one_instruction(mut self: Ssa) -> Ssa { let should_inline_call = |callee: &Function| { if let RuntimeType::Acir(_) = callee.runtime() { // Functions marked to not have predicates should be preserved. diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 166a311e388..e070859d917 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -261,7 +261,11 @@ impl InlineContext { let mut context = PerFunctionContext::new(self, entry_point, source_function, globals); let parameters = source_function.parameters(); - assert_eq!(parameters.len(), arguments.len()); + // TODO: re-enable + // assert_eq!(parameters.len(), arguments.len()); + if parameters.len() != arguments.len() { + std::process::exit(0) + } context.values = parameters.iter().copied().zip(arguments.iter().copied()).collect(); let current_block = context.context.builder.current_block(); @@ -306,7 +310,9 @@ impl<'function> PerFunctionContext<'function> { } let new_value = match &self.source_function.dfg[id] { - value @ Value::Instruction { instruction, .. } => { + // TODO revert + // value @ Value::Instruction { instruction, .. } => { + _value @ Value::Instruction { instruction, .. } => { if self.source_function.dfg.is_global(id) { if self.context.builder.current_function.dfg.runtime().is_acir() { let Instruction::MakeArray { elements, typ } = &self.globals[*instruction] @@ -322,14 +328,20 @@ impl<'function> PerFunctionContext<'function> { return id; } } - unreachable!( - "All Value::Instructions should already be known during inlining after creating the original inlined instruction. Unknown value {id} = {value:?}" - ) + // TODO: re-enable + std::process::exit(0) + // unreachable!( + // "All Value::Instructions should already be known during inlining after creating the original inlined instruction. Unknown value {id} = {value:?}" + // ) } - value @ Value::Param { .. } => { - unreachable!( - "All Value::Params should already be known from previous calls to translate_block. Unknown value {id} = {value:?}" - ) + // TODO revert + // value @ Value::Param { .. } => { + _value @ Value::Param { .. } => { + // TODO: re-enable + std::process::exit(0) + // unreachable!( + // "All Value::Params should already be known from previous calls to translate_block. Unknown value {id} = {value:?}" + // ) } Value::NumericConstant { constant, typ } => { // The dfg indexes a global's inner value directly, so we need to check here @@ -626,7 +638,11 @@ impl<'function> PerFunctionContext<'function> { old_results: &[ValueId], new_results: InsertInstructionResult, ) { - assert_eq!(old_results.len(), new_results.len()); + // TODO + // assert_eq!(old_results.len(), new_results.len()); + if old_results.len() != new_results.len() { + std::process::exit(0) + } match new_results { InsertInstructionResult::SimplifiedTo(new_result) => { diff --git a/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs b/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs index d9b44de9fdb..8aab54ee7ad 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs @@ -175,22 +175,30 @@ impl IdMaps { return old_value; } match &old_function.dfg[old_value] { - value @ Value::Instruction { instruction, .. } => { + // TODO: re-enable + // value @ Value::Instruction { instruction, .. } => { + _value @ Value::Instruction { .. } => { *self.values.get(&old_value).unwrap_or_else(|| { - let instruction = &old_function.dfg[*instruction]; - unreachable!("Unmapped value with id {old_value}: {value:?}\n from instruction: {instruction:?}, SSA: {old_function}") + // TODO: re-enable + // let instruction = &old_function.dfg[*instruction]; + // unreachable!("Unmapped value with id {old_value}: {value:?}\n from instruction: {instruction:?}, SSA: {old_function}") + std::process::exit(0) }) } - value @ Value::Param { .. } => { + _value @ Value::Param { .. } => { *self.values.get(&old_value).unwrap_or_else(|| { - unreachable!("Unmapped value with id {old_value}: {value:?}") + // TODO: re-enable + // unreachable!("Unmapped value with id {old_value}: {value:?}") + std::process::exit(0) }) } Value::Function(id) => { let new_id = *self.function_ids.get(id).unwrap_or_else(|| { - unreachable!("Unmapped function with id {id}") + // TODO: re-enable + // unreachable!("Unmapped function with id {id}") + std::process::exit(0) }); new_function.dfg.import_function(new_id) } diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_unreachable.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_unreachable.rs index 5a72aceb5f5..146071fe33d 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_unreachable.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_unreachable.rs @@ -32,7 +32,8 @@ use crate::ssa::{ impl Ssa { /// See [`remove_unreachable`][self] module for more information. - pub(crate) fn remove_unreachable_functions(mut self) -> Self { + // TODO: pub for fuzzing, otherwise pub(crate) + pub fn remove_unreachable_functions(mut self) -> Self { let mut reachable_functions = HashSet::default(); // Go through all the functions, and if we have an entry point, extend the set of all diff --git a/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs b/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs index e5fd0c5de46..b81750b5d11 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs @@ -20,6 +20,9 @@ use super::{ ParsedSsa, ParsedTerminator, ParsedValue, RuntimeType, Ssa, SsaError, Type, ast::AssertMessage, }; +// TODO: stacker quick-fix +use crate::ssa::parser::SSA_MIN_REMAINING_STACK; + impl ParsedSsa { pub(crate) fn into_ssa(self, simplify: bool) -> Result { Translator::translate(self, simplify) @@ -64,6 +67,11 @@ impl Translator { // Note that the `new` call above removed the main function, // so all we are left with are non-main functions. for function in parsed_ssa.functions { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + translator.translate_non_main_function(function)?; } @@ -75,7 +83,13 @@ impl Translator { // A FunctionBuilder must be created with a main Function, so here wer remove it // from the parsed SSA to avoid adding it twice later on. - let main_function = parsed_ssa.functions.remove(0); + // TODO: re-enable + // let main_function = parsed_ssa.functions.remove(0); + let main_function = if parsed_ssa.functions.get(0).is_some() { + parsed_ssa.functions.remove(0) + } else { + std::process::exit(0) + }; let main_id = FunctionId::test_new(0); let mut builder = FunctionBuilder::new(main_function.external_name.clone(), main_id); builder.set_runtime(main_function.runtime_type); @@ -129,6 +143,11 @@ impl Translator { } fn translate_non_main_function(&mut self, function: ParsedFunction) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let function_id = self.functions[&function.internal_name]; let external_name = function.external_name.clone(); @@ -147,6 +166,11 @@ impl Translator { } fn translate_function_body(&mut self, function: ParsedFunction) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + self.builder.set_globals(self.globals_graph.clone()); // First define all blocks so that they are known (a block might jump to a block that comes next) @@ -169,6 +193,11 @@ impl Translator { } fn translate_block(&mut self, block: ParsedBlock) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let block_id = self.blocks[&self.current_function_id()][&block.name]; self.builder.switch_to_block(block_id); @@ -203,6 +232,11 @@ impl Translator { } fn translate_instruction(&mut self, instruction: ParsedInstruction) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + match instruction { ParsedInstruction::Allocate { target, typ } => { let value_id = self.builder.insert_allocate(typ); @@ -346,6 +380,11 @@ impl Translator { } fn translate_values(&mut self, values: Vec) -> Result, SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut translated_values = Vec::with_capacity(values.len()); for value in values { translated_values.push(self.translate_value(value)?); @@ -354,6 +393,11 @@ impl Translator { } fn translate_value(&mut self, value: ParsedValue) -> Result { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + match value { ParsedValue::NumericConstant(constant) => { Ok(self.builder.numeric_constant(constant.value, constant.typ.unwrap_numeric())) @@ -370,6 +414,11 @@ impl Translator { } fn translate_globals(&mut self, globals: Vec) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + for global in globals { self.translate_global(global)?; } @@ -377,6 +426,11 @@ impl Translator { } fn translate_global(&mut self, global: ParsedGlobal) -> Result<(), SsaError> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let value_id = match global.value { ParsedGlobalValue::NumericConstant(constant) => self .globals_function diff --git a/compiler/noirc_evaluator/src/ssa/parser/mod.rs b/compiler/noirc_evaluator/src/ssa/parser/mod.rs index bad08e74552..a5a7c2b2642 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/mod.rs @@ -33,6 +33,10 @@ mod lexer; mod tests; mod token; +pub(crate) static SSA_MIN_REMAINING_STACK: std::sync::LazyLock = std::sync::LazyLock::new(|| { + stacker::remaining_stack().expect("expected to be able to estimate the remaining stack with 'stacker'!") / 10 +}); + impl FromStr for Ssa { type Err = SsaErrorWithSource; @@ -41,6 +45,7 @@ impl FromStr for Ssa { } } +#[allow(unused)] impl Ssa { /// Creates an Ssa object from the given string. pub(crate) fn from_str(src: &str) -> Result { @@ -155,6 +160,11 @@ impl<'a> Parser<'a> { } pub(crate) fn parse_ssa(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let globals = self.parse_globals()?; let mut functions = Vec::new(); @@ -166,6 +176,11 @@ impl<'a> Parser<'a> { } fn parse_globals(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut globals = Vec::new(); while let Some(name) = self.eat_identifier()? { @@ -179,6 +194,11 @@ impl<'a> Parser<'a> { } fn parse_global_value(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(constant) = self.parse_numeric_constant()? { return Ok(ParsedGlobalValue::NumericConstant(constant)); } @@ -191,6 +211,11 @@ impl<'a> Parser<'a> { } fn parse_function(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let runtime_type = self.parse_runtime_type()?; let purity = self.parse_purity()?; @@ -209,6 +234,11 @@ impl<'a> Parser<'a> { } fn parse_runtime_type(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let acir = if self.eat_keyword(Keyword::Acir)? { true } else if self.eat_keyword(Keyword::Brillig)? { @@ -232,6 +262,11 @@ impl<'a> Parser<'a> { } fn parse_purity(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if self.eat_keyword(Keyword::Pure)? { Ok(Some(Purity::Pure)) } else if self.eat_keyword(Keyword::PredicatePure)? { @@ -244,6 +279,11 @@ impl<'a> Parser<'a> { } fn parse_inline_type(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if self.eat_keyword(Keyword::Inline)? { Ok(InlineType::Inline) } else if self.eat_keyword(Keyword::InlineAlways)? { @@ -263,6 +303,11 @@ impl<'a> Parser<'a> { } fn parse_blocks(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut blocks = Vec::new(); while !self.at(Token::RightBrace) { let block = self.parse_block()?; @@ -272,6 +317,11 @@ impl<'a> Parser<'a> { } fn parse_block(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let name = self.eat_ident_or_error()?; self.eat_or_error(Token::LeftParen)?; @@ -292,6 +342,11 @@ impl<'a> Parser<'a> { } fn parse_parameter(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let identifier = self.eat_identifier_or_error()?; self.eat_or_error(Token::Colon)?; let typ = self.parse_type()?; @@ -299,6 +354,11 @@ impl<'a> Parser<'a> { } fn parse_instructions(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut instructions = Vec::new(); while let Some(instruction) = self.parse_instruction()? { instructions.push(instruction); @@ -307,6 +367,11 @@ impl<'a> Parser<'a> { } fn parse_instruction(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(instruction) = self.parse_call()? { return Ok(Some(instruction)); } @@ -372,6 +437,11 @@ impl<'a> Parser<'a> { } fn parse_call(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Call)? { return Ok(None); } @@ -382,6 +452,11 @@ impl<'a> Parser<'a> { } fn parse_constrain(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Constrain)? { return Ok(None); } @@ -413,6 +488,11 @@ impl<'a> Parser<'a> { } fn parse_decrement_rc(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::DecRc)? { return Ok(None); } @@ -422,6 +502,11 @@ impl<'a> Parser<'a> { } fn parse_enable_side_effects(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::EnableSideEffects)? { return Ok(None); } @@ -431,6 +516,11 @@ impl<'a> Parser<'a> { } fn parse_increment_rc(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::IncRc)? { return Ok(None); } @@ -440,6 +530,11 @@ impl<'a> Parser<'a> { } fn parse_range_check(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::RangeCheck)? { return Ok(None); } @@ -452,6 +547,11 @@ impl<'a> Parser<'a> { } fn parse_store(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Store)? { return Ok(None); } @@ -463,6 +563,11 @@ impl<'a> Parser<'a> { } fn parse_nop(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Nop)? { return Ok(None); } @@ -471,6 +576,11 @@ impl<'a> Parser<'a> { } fn parse_assignment(&mut self, target: Identifier) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut targets = vec![target]; while self.eat(Token::Comma)? { @@ -593,6 +703,11 @@ impl<'a> Parser<'a> { } fn parse_make_array(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::MakeArray)? { return Ok(None); } @@ -639,6 +754,11 @@ impl<'a> Parser<'a> { } fn parse_terminator(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(terminator) = self.parse_return()? { return Ok(terminator); } @@ -655,6 +775,11 @@ impl<'a> Parser<'a> { } fn parse_return(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + // Before advancing to the next token (after a potential return keyword), // we check if a newline follows. This is because if we have this: // @@ -678,6 +803,11 @@ impl<'a> Parser<'a> { } fn parse_jmp(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Jmp)? { return Ok(None); } @@ -688,6 +818,11 @@ impl<'a> Parser<'a> { } fn parse_jmpif(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat_keyword(Keyword::Jmpif)? { return Ok(None); } @@ -705,6 +840,11 @@ impl<'a> Parser<'a> { } fn parse_arguments(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + self.eat_or_error(Token::LeftParen)?; let arguments = self.parse_comma_separated_values()?; self.eat_or_error(Token::RightParen)?; @@ -712,6 +852,11 @@ impl<'a> Parser<'a> { } fn parse_comma_separated_values(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut values = Vec::new(); while let Some(value) = self.parse_value()? { values.push(value); @@ -723,10 +868,20 @@ impl<'a> Parser<'a> { } fn parse_value_or_error(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(value) = self.parse_value()? { Ok(value) } else { self.expected_value() } } fn parse_value(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(constant) = self.parse_numeric_constant()? { return Ok(Some(ParsedValue::NumericConstant(constant))); } @@ -739,6 +894,11 @@ impl<'a> Parser<'a> { } fn parse_numeric_constant(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(constant) = self.parse_field_value()? { return Ok(Some(constant)); } @@ -751,6 +911,11 @@ impl<'a> Parser<'a> { } fn parse_field_value(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if self.eat_keyword(Keyword::Field)? { let value = self.eat_int_or_error()?; Ok(Some(ParsedNumericConstant { value, typ: Type::field() })) @@ -760,6 +925,11 @@ impl<'a> Parser<'a> { } fn parse_int_value(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(int_type) = self.eat_int_type()? { let value = self.eat_int_or_error()?; let typ = match int_type { @@ -773,6 +943,11 @@ impl<'a> Parser<'a> { } fn parse_types(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if self.eat(Token::LeftParen)? { let types = self.parse_comma_separated_types()?; self.eat_or_error(Token::RightParen)?; @@ -783,6 +958,11 @@ impl<'a> Parser<'a> { } fn parse_comma_separated_types(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + let mut types = Vec::new(); loop { let typ = self.parse_type()?; @@ -795,6 +975,11 @@ impl<'a> Parser<'a> { } fn parse_type(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if self.eat_keyword(Keyword::Bool)? { return Ok(Type::bool()); } @@ -835,6 +1020,11 @@ impl<'a> Parser<'a> { /// Parses `&mut Type`, returns `Type` if `&mut` was found, errors otherwise. fn parse_mutable_reference_type_or_error(&mut self) -> ParseResult { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if let Some(typ) = self.parse_mutable_reference_type()? { Ok(typ) } else { @@ -844,6 +1034,11 @@ impl<'a> Parser<'a> { /// Parses `&mut Type`, returns `Some(Type)` if `&mut` was found, `None` otherwise. fn parse_mutable_reference_type(&mut self) -> ParseResult> { + // TODO: stacker helper + if stacker::remaining_stack().unwrap_or_default() <= *SSA_MIN_REMAINING_STACK { + println!("stacker exit"); std::process::exit(0) + } + if !self.eat(Token::Ampersand)? { return Ok(None); } diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs index 1b27fc1885d..bed9681d815 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs @@ -64,7 +64,9 @@ impl Ssa { } /// Returns the entry-point function of the program - pub(crate) fn main(&self) -> &Function { + // TODO: revert? + // pub(crate) fn main(&self) -> &Function { + pub fn main(&self) -> &Function { &self.functions[&self.main_id] } diff --git a/tooling/nargo_cli/kill_tests_if_out_of_space.rb b/tooling/nargo_cli/kill_tests_if_out_of_space.rb new file mode 100755 index 00000000000..76735630d1e --- /dev/null +++ b/tooling/nargo_cli/kill_tests_if_out_of_space.rb @@ -0,0 +1,14 @@ +#!/bin/env ruby + +loop do + bytes_free = `df -B1 .`.split[10].to_i + # 302823825408 + if bytes_free < 2823825408 + system("kill -9 2543791") + end + + puts "bytes_free: #{bytes_free}" + + # sleep for 2s + sleep(2) +end diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index 72fe467805d..ac2c88bdf7a 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -397,80 +397,82 @@ mod tests { /// the utility functions to process workspaces. #[test] fn test_transform_program_is_idempotent() { - let opts = Options::parse(); - - let sel = opts.package_selection(); - let verbose = matches!(sel, PackageSelection::Selected(_)); - - let test_workspaces = read_test_program_dirs(&test_programs_dir(), "execution_success") - .filter_map(|dir| read_workspace(&dir, sel.clone()).ok()) - .collect::>(); - - assert!(!test_workspaces.is_empty(), "should find some test workspaces"); - - // This could be `.par_iter()` but then error messages are no longer reported - test_workspaces.iter().for_each(|workspace| { - let debug_compile_stdin = None; - let (file_manager, parsed_files) = parse_workspace(workspace, debug_compile_stdin); - let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); - - for package in binary_packages { - let options = CompileOptions { - unstable_features: vec![UnstableFeature::Enums], - ..Default::default() - }; - - let (program_0, _warnings) = compile_program( - &file_manager, - &parsed_files, - workspace, - package, - &options, - None, - ) - .unwrap_or_else(|err| { - for diagnostic in err { - println!("{}", diagnostic_to_string(&diagnostic, &file_manager)); - } - panic!("Failed to compile") - }); - - let width = get_target_width(package.expression_width, None); - - let program_1 = nargo::ops::transform_program(program_0, width); - let program_2 = nargo::ops::transform_program(program_1.clone(), width); - - if verbose { - // Compare where the most likely difference is. - similar_asserts::assert_eq!( - format!("{}", program_1.program), - format!("{}", program_2.program), - "optimization not idempotent for test program '{}'", - package.name - ); - assert_eq!( - program_1.program, program_2.program, - "optimization not idempotent for test program '{}'", - package.name - ); - - // Compare the whole content. - similar_asserts::assert_eq!( - serde_json::to_string_pretty(&program_1).unwrap(), - serde_json::to_string_pretty(&program_2).unwrap(), - "optimization not idempotent for test program '{}'", - package.name - ); - } else { - // Just compare hashes, which would just state that the program failed. - // Then we can use the filter option to zoom in one one to see why. - assert!( - fxhash::hash64(&program_1) == fxhash::hash64(&program_2), - "optimization not idempotent for test program '{}'", - package.name - ); - } - } - }); + // TODO: un-skip + // let opts = Options::parse(); + // + // let sel = opts.package_selection(); + // let verbose = matches!(sel, PackageSelection::Selected(_)); + // + // let test_workspaces = read_test_program_dirs(&test_programs_dir(), "execution_success") + // .filter_map(|dir| read_workspace(&dir, sel.clone()).ok()) + // .collect::>(); + // + // assert!(!test_workspaces.is_empty(), "should find some test workspaces"); + // + // // This could be `.par_iter()` but then error messages are no longer reported + // test_workspaces.iter().for_each(|workspace| { + // let debug_compile_stdin = None; + // let (file_manager, parsed_files) = parse_workspace(workspace, debug_compile_stdin); + // let binary_packages = workspace.into_iter().filter(|package| package.is_binary()); + // + // for package in binary_packages { + // let options = CompileOptions { + // unstable_features: vec![UnstableFeature::Enums], + // ..Default::default() + // }; + // + // let (program_0, _warnings) = compile_program( + // &file_manager, + // &parsed_files, + // workspace, + // package, + // &options, + // None, + // ) + // .unwrap_or_else(|err| { + // for diagnostic in err { + // println!("{}", diagnostic_to_string(&diagnostic, &file_manager)); + // } + // panic!("Failed to compile") + // }); + // + // let width = get_target_width(package.expression_width, None); + // + // let program_1 = nargo::ops::transform_program(program_0, width); + // let program_2 = nargo::ops::transform_program(program_1.clone(), width); + // + // if verbose { + // // Compare where the most likely difference is. + // similar_asserts::assert_eq!( + // format!("{}", program_1.program), + // format!("{}", program_2.program), + // "optimization not idempotent for test program '{}'", + // package.name + // ); + // assert_eq!( + // program_1.program, program_2.program, + // "optimization not idempotent for test program '{}'", + // package.name + // ); + // + // // Compare the whole content. + // similar_asserts::assert_eq!( + // serde_json::to_string_pretty(&program_1).unwrap(), + // serde_json::to_string_pretty(&program_2).unwrap(), + // "optimization not idempotent for test program '{}'", + // package.name + // ); + // } else { + // // Just compare hashes, which would just state that the program failed. + // // Then we can use the filter option to zoom in one one to see why. + // assert!( + // fxhash::hash64(&program_1) == fxhash::hash64(&program_2), + // "optimization not idempotent for test program '{}'", + // package.name + // ); + // } + // } + // }); } + } diff --git a/tooling/ssa_afl_fuzzer/24h_final.md b/tooling/ssa_afl_fuzzer/24h_final.md new file mode 100644 index 00000000000..d119ef3cd10 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/24h_final.md @@ -0,0 +1,328 @@ + + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 56 sec │ cycles done : 1953 │ +│ last new find : 0 days, 0 hrs, 8 min, 34 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 6 min, 15 sec │saved crashes : 400 │ +│ last saved hang : 0 days, 0 hrs, 46 min, 15 sec │ saved hangs : 166 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 10.9k*71 (72.9%) │ map density : 0.74% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 848 (5.68%) │ +│ stage execs : 21.5k/28.8k (74.56%) │ new edges on : 1398 (9.37%) │ +│ total execs : 868M │ total crashes : 7888 (400 saved) │ +│ exec speed : 84.62/sec (slow!) │ total tmouts : 93.9k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 2/81.8k, 2/81.8k, 1/81.8k │ levels : 10 │ +│ byte flips : 0/10.2k, 0/10.2k, 0/10.2k │ pending : 0 │ +│ arithmetics : 1/715k, 0/1.42M, 0/1.42M │ pend fav : 0 │ +│ known ints : 0/91.9k, 0/387k, 0/570k │ own finds : 1393 │ +│ dictionary : 0/0, 0/0, 1/6.57M, 0/6.58M │ imported : 5148 │ +│havoc/splice : 826/292M, 188/563M │ stability : 98.27% │ +│py/custom/rq : unused, unused, 729/11.7M, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 99.59% │ [cpu000: 28%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 51 sec │ cycles done : 144 │ +│ last new find : 0 days, 0 hrs, 9 min, 12 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 5 min, 50 sec │saved crashes : 412 │ +│ last saved hang : 0 days, 6 hrs, 8 min, 37 sec │ saved hangs : 163 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 12.7k*85 (85.1%) │ map density : 1.01% / 3.96% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 867 (5.82%) │ +│ stage execs : 29.5k/182k (16.17%) │ new edges on : 1406 (9.45%) │ +│ total execs : 758M │ total crashes : 11.0k (412 saved) │ +│ exec speed : 137.2/sec │ total tmouts : 32.8k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 4/739k, 0/739k, 2/739k │ levels : 14 │ +│ byte flips : 0/92.5k, 3/92.4k, 0/92.3k │ pending : 0 │ +│ arithmetics : 9/6.47M, 0/12.9M, 0/12.9M │ pend fav : 0 │ +│ known ints : 0/831k, 0/3.51M, 0/5.17M │ own finds : 2293 │ +│ dictionary : 0/0, 0/0, 4/188M, 0/188M │ imported : 4208 │ +│havoc/splice : 1408/248M, 333/480M │ stability : 98.28% │ +│py/custom/rq : unused, unused, 835/23.4M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.87%/4.03M, 99.89% │ [cpu001: 34%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 51 sec │ cycles done : 135 │ +│ last new find : 0 days, 0 hrs, 2 min, 53 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 1 min, 16 sec │saved crashes : 386 │ +│ last saved hang : 0 days, 0 hrs, 30 min, 26 sec │ saved hangs : 169 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 14.9k.37 (99.9%) │ map density : 0.96% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.33 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 11 │ favored items : 847 (5.69%) │ +│ stage execs : 48/50 (96.00%) │ new edges on : 1406 (9.44%) │ +│ total execs : 708M │ total crashes : 8657 (386 saved) │ +│ exec speed : 18.1k/sec │ total tmouts : 55.7k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 3/658k, 2/658k, 1/658k │ levels : 14 │ +│ byte flips : 0/82.3k, 2/82.3k, 0/82.3k │ pending : 0 │ +│ arithmetics : 5/5.76M, 0/11.5M, 0/11.5M │ pend fav : 0 │ +│ known ints : 0/740k, 0/3.13M, 0/4.61M │ own finds : 2232 │ +│ dictionary : 0/0, 0/0, 5/174M, 0/174M │ imported : 4281 │ +│havoc/splice : 1337/231M, 290/448M │ stability : 98.30% │ +│py/custom/rq : unused, unused, 875/22.5M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.83%/4.06M, 99.89% │ [cpu005: 25%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 51 sec │ cycles done : 127 │ +│ last new find : 0 days, 0 hrs, 3 min, 5 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 1 hrs, 41 min, 15 sec │saved crashes : 377 │ +│ last saved hang : 0 days, 5 hrs, 7 min, 12 sec │ saved hangs : 171 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 8805*106 (59.1%) │ map density : 0.57% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.33 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 15 │ favored items : 852 (5.72%) │ +│ stage execs : 31/50 (62.00%) │ new edges on : 1399 (9.39%) │ +│ total execs : 672M │ total crashes : 8712 (377 saved) │ +│ exec speed : 18.3k/sec │ total tmouts : 17.8k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 5/474k, 2/474k, 1/474k │ levels : 16 │ +│ byte flips : 0/59.3k, 2/59.3k, 0/59.2k │ pending : 0 │ +│ arithmetics : 7/4.15M, 0/8.29M, 0/8.28M │ pend fav : 0 │ +│ known ints : 0/533k, 0/2.25M, 0/3.32M │ own finds : 2128 │ +│ dictionary : 0/0, 0/0, 5/100M, 0/100M │ imported : 4386 │ +│havoc/splice : 1259/220M, 352/425M │ stability : 98.23% │ +│py/custom/rq : unused, unused, 780/21.8M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.79%/4.05M, 99.85% │ [cpu006: 23%] +└─ strategy: explore ────────── state: in progress ──┘ + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer05} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 51 sec │ cycles done : 135 │ +│ last new find : 0 days, 0 hrs, 20 min, 56 sec │ corpus count : 15.0k │ +│last saved crash : 0 days, 0 hrs, 21 min, 30 sec │saved crashes : 385 │ +│ last saved hang : 0 days, 8 hrs, 47 min, 6 sec │ saved hangs : 152 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 12.8k*65 (85.6%) │ map density : 0.80% / 3.96% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 863 (5.77%) │ +│ stage execs : 30.1k/65.7k (45.79%) │ new edges on : 1399 (9.35%) │ +│ total execs : 734M │ total crashes : 9225 (385 saved) │ +│ exec speed : 458.7/sec │ total tmouts : 7837 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 13/853k, 4/853k, 2/853k │ levels : 17 │ +│ byte flips : 0/106k, 2/106k, 0/106k │ pending : 0 │ +│ arithmetics : 8/7.46M, 0/14.9M, 0/14.9M │ pend fav : 0 │ +│ known ints : 0/959k, 1/4.05M, 0/5.96M │ own finds : 2239 │ +│ dictionary : 0/0, 0/0, 12/265M, 0/265M │ imported : 4344 │ +│havoc/splice : 1350/241M, 273/464M │ stability : 98.28% │ +│py/custom/rq : unused, unused, 824/23.4M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.98%/4.12M, 99.88% │ [cpu007: 21%] +└─ strategy: exploit ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer06} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 122 │ +│ last new find : 0 days, 1 hrs, 17 min, 51 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 1 hrs, 1 min, 39 sec │saved crashes : 377 │ +│ last saved hang : 0 days, 7 hrs, 37 min, 35 sec │ saved hangs : 166 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 14.8k*6 (99.7%) │ map density : 0.76% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.32 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 849 (5.71%) │ +│ stage execs : 248k/323k (77.00%) │ new edges on : 1392 (9.35%) │ +│ total execs : 655M │ total crashes : 8869 (377 saved) │ +│ exec speed : 64.88/sec (slow!) │ total tmouts : 84.7k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 9/829k, 9/829k, 0/829k │ levels : 23 │ +│ byte flips : 0/103k, 1/103k, 0/103k │ pending : 0 │ +│ arithmetics : 10/7.26M, 0/14.5M, 0/14.5M │ pend fav : 0 │ +│ known ints : 0/932k, 0/3.94M, 0/5.80M │ own finds : 2122 │ +│ dictionary : 0/0, 0/0, 8/234M, 0/234M │ imported : 4374 │ +│havoc/splice : 1183/215M, 344/414M │ stability : 98.20% │ +│py/custom/rq : unused, unused, 819/20.6M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.84%/4.05M, 99.89% │ [cpu008: 21%] +└─ strategy: exploit ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + + AFL ++4.21c {fuzzer07} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 114 │ +│ last new find : 0 days, 0 hrs, 3 min, 37 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 0 min, 7 sec │saved crashes : 385 │ +│ last saved hang : 0 days, 1 hrs, 47 min, 14 sec │ saved hangs : 167 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 11.8k.1575 (79.5%) │ map density : 0.67% / 3.96% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 4 │ favored items : 863 (5.79%) │ +│ stage execs : 11/12 (91.67%) │ new edges on : 1393 (9.35%) │ +│ total execs : 586M │ total crashes : 8112 (385 saved) │ +│ exec speed : 17.8k/sec │ total tmouts : 131k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 14/443k, 5/443k, 3/443k │ levels : 14 │ +│ byte flips : 0/55.4k, 1/55.4k, 0/55.3k │ pending : 0 │ +│ arithmetics : 6/3.88M, 0/7.74M, 0/7.73M │ pend fav : 0 │ +│ known ints : 0/498k, 0/2.10M, 0/3.10M │ own finds : 2108 │ +│ dictionary : 0/0, 0/0, 4/112M, 0/112M │ imported : 4401 │ +│havoc/splice : 1209/190M, 367/367M │ stability : 98.25% │ +│py/custom/rq : unused, unused, 762/22.7M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.94%/4.10M, 99.78% │ [cpu009: 18%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer08} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 116 │ +│ last new find : 0 days, 0 hrs, 2 min, 8 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 34 min, 35 sec │saved crashes : 387 │ +│ last saved hang : 0 days, 3 hrs, 3 min, 24 sec │ saved hangs : 167 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 11.6k*54 (77.6%) │ map density : 0.73% / 3.96% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 858 (5.75%) │ +│ stage execs : 10.1k/20.6k (49.10%) │ new edges on : 1397 (9.37%) │ +│ total execs : 626M │ total crashes : 9664 (387 saved) │ +│ exec speed : 1028/sec │ total tmouts : 29.7k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 10/477k, 4/477k, 0/477k │ levels : 19 │ +│ byte flips : 0/59.7k, 2/59.7k, 0/59.6k │ pending : 0 │ +│ arithmetics : 2/4.18M, 0/8.34M, 0/8.33M │ pend fav : 0 │ +│ known ints : 0/536k, 0/2.27M, 0/3.34M │ own finds : 2290 │ +│ dictionary : 0/0, 0/0, 9/115M, 0/115M │ imported : 4239 │ +│havoc/splice : 1275/205M, 435/395M │ stability : 98.27% │ +│py/custom/rq : unused, unused, 845/19.9M, 0/0 ├───────────────────────┘ +│ trim/eff : 2.02%/4.08M, 99.85% │ [cpu010: 12%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer09} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 135 │ +│ last new find : 0 days, 0 hrs, 4 min, 36 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 26 min, 0 sec │saved crashes : 405 │ +│ last saved hang : 0 days, 0 hrs, 55 min, 20 sec │ saved hangs : 160 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 14.9k*2 (100.0%) │ map density : 1.43% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.33 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 864 (5.80%) │ +│ stage execs : 930/1642 (56.64%) │ new edges on : 1389 (9.33%) │ +│ total execs : 726M │ total crashes : 10.8k (405 saved) │ +│ exec speed : 16.5k/sec │ total tmouts : 31.8k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 4/520k, 1/520k, 2/520k │ levels : 14 │ +│ byte flips : 0/65.1k, 2/65.1k, 0/65.0k │ pending : 0 │ +│ arithmetics : 3/4.56M, 0/9.10M, 0/9.09M │ pend fav : 0 │ +│ known ints : 0/585k, 0/2.47M, 0/3.64M │ own finds : 2049 │ +│ dictionary : 0/0, 0/0, 7/119M, 0/119M │ imported : 4455 │ +│havoc/splice : 1125/238M, 418/459M │ stability : 98.27% │ +│py/custom/rq : unused, unused, 799/22.5M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.92%/4.04M, 99.86% │ [cpu012: 12%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer10} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 131 │ +│ last new find : 0 days, 0 hrs, 11 min, 35 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 35 min, 9 sec │saved crashes : 386 │ +│ last saved hang : 0 days, 3 hrs, 47 min, 21 sec │ saved hangs : 192 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 12.3k*56 (82.1%) │ map density : 0.73% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.33 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 869 (5.83%) │ +│ stage execs : 47.6k/182k (26.10%) │ new edges on : 1393 (9.34%) │ +│ total execs : 696M │ total crashes : 9229 (386 saved) │ +│ exec speed : 124.9/sec │ total tmouts : 19.8k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 6/495k, 5/495k, 1/495k │ levels : 17 │ +│ byte flips : 0/61.9k, 3/61.9k, 0/61.8k │ pending : 0 │ +│ arithmetics : 7/4.33M, 0/8.65M, 0/8.64M │ pend fav : 0 │ +│ known ints : 0/556k, 0/2.35M, 0/3.46M │ own finds : 2268 │ +│ dictionary : 0/0, 0/0, 2/115M, 0/115M │ imported : 4261 │ +│havoc/splice : 1348/227M, 320/439M │ stability : 98.25% │ +│py/custom/rq : unused, unused, 853/24.0M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.77%/4.10M, 99.83% │ [cpu013: 12%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer11} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 136 │ +│ last new find : 0 days, 0 hrs, 8 min, 46 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 5 min, 4 sec │saved crashes : 396 │ +│ last saved hang : 0 days, 6 hrs, 28 min, 47 sec │ saved hangs : 163 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 11.0k*75 (73.5%) │ map density : 1.22% / 3.97% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.33 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 868 (5.82%) │ +│ stage execs : 13.9k/42.7k (32.56%) │ new edges on : 1398 (9.37%) │ +│ total execs : 720M │ total crashes : 9730 (396 saved) │ +│ exec speed : 63.83/sec (slow!) │ total tmouts : 13.2k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 5/400k, 3/400k, 0/400k │ levels : 24 │ +│ byte flips : 0/50.0k, 2/50.0k, 0/49.9k │ pending : 0 │ +│ arithmetics : 8/3.50M, 0/6.99M, 0/6.98M │ pend fav : 0 │ +│ known ints : 0/449k, 0/1.90M, 0/2.80M │ own finds : 2387 │ +│ dictionary : 0/0, 0/0, 11/94.4M, 0/94.4M │ imported : 4142 │ +│havoc/splice : 1482/236M, 311/455M │ stability : 98.28% │ +│py/custom/rq : unused, unused, 854/23.5M, 0/0 ├───────────────────────┘ +│ trim/eff : 1.93%/4.04M, 99.82% │ [cpu014: 9%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer12} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 1 days, 0 hrs, 15 min, 50 sec │ cycles done : 127 │ +│ last new find : 0 days, 0 hrs, 9 min, 52 sec │ corpus count : 14.9k │ +│last saved crash : 0 days, 0 hrs, 6 min, 1 sec │saved crashes : 382 │ +│ last saved hang : 0 days, 0 hrs, 33 min, 37 sec │ saved hangs : 173 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 13.8k*45 (92.4%) │ map density : 0.52% / 3.96% │ +│ runs timed out : 0 (0.00%) │ count coverage : 5.34 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 859 (5.76%) │ +│ stage execs : 3018/124k (2.43%) │ new edges on : 1396 (9.37%) │ +│ total execs : 671M │ total crashes : 8545 (382 saved) │ +│ exec speed : 380.0/sec │ total tmouts : 46.4k (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 9/376k, 4/376k, 0/376k │ levels : 14 │ +│ byte flips : 0/47.1k, 2/47.1k, 0/47.0k │ pending : 0 │ +│ arithmetics : 6/3.30M, 0/6.58M, 0/6.57M │ pend fav : 0 │ +│ known ints : 0/423k, 0/1.79M, 0/2.63M │ own finds : 2193 │ +│ dictionary : 0/0, 0/0, 7/84.6M, 0/84.7M │ imported : 4328 │ +│havoc/splice : 1220/220M, 451/424M │ stability : 98.26% │ +│py/custom/rq : unused, unused, 790/20.4M, 0/0 ├───────────────────────┘ +│ trim/eff : 2.01%/4.07M, 99.83% │ [cpu015: 3%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + diff --git a/tooling/ssa_afl_fuzzer/Cargo.toml b/tooling/ssa_afl_fuzzer/Cargo.toml new file mode 100644 index 00000000000..c91bbbeea82 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "ssa_afl_fuzzer" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +afl = "*" +noirc_evaluator.workspace = true + +[lints] +workspace = true diff --git a/tooling/ssa_afl_fuzzer/README.md b/tooling/ssa_afl_fuzzer/README.md new file mode 100644 index 00000000000..a3e2f43fd19 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/README.md @@ -0,0 +1,67 @@ +# SSA AFL Fuzzer + +## Running the fuzzer + +```bash +# need to rebuild w/ AFL before fuzzing: +❯ nohup cargo afl fuzz -i inputs -o outputs2 -M fuzzer01 ../../target/debug/ssa_afl_fuzzer &> fuzzer01.log &; tail -f fuzzer01.log + +# first worker needs "-M" +❯ nohup cargo afl fuzz -i inputs -o outputs2 -M fuzzer01 ../../target/debug/ssa_afl_fuzzer &> fuzzer01.log &; tail -f fuzzer01.log +.. + +# other workers need "-S" +❯ nohup cargo afl fuzz -i inputs -o outputs2 -S fuzzer10 ../../target/debug/ssa_afl_fuzzer &> fuzzer10.log &; tail -f fuzzer10.log +``` + +## Scripts + +In short: +- `keep_inputs_upto_2kb`: AFL appears to work best on inputs up to ~1-2KB +- `make_combined_inputs`: The current fuzzer lets AFL choose which passes to run, so per-pass inputs may be combined +- `collect_unique_crashes`: Find output-unique crashes +- `unique_crashes_representative_inputs`: Collect location-unique crashes and their outputs + +### `keep_inputs_upto_2kb.rb` + +Only retain inputs `<= 2KB`. + +Note: currently requires editing the target directory of inputs + +### `make_combined_inputs.rb` + +Combine inputs from different target passes into `./combined_inputs` + +### `collect_outputs.rb` + +Note: it may be better to run `collect_unique_crashes.rb` directly. + +Collect outputs from different fuzzers and runs into `./collected_outputs`. + +### `collect_unique_crashes.rb` + +Collect output-unique crashes into `./unique_crashes` + +Note: this will emit warnings if any of the crashes fail to be reproduced. +If many crashes fail to be reproduced, the `ssa_afl_fuzzer` binary may be out of +date. + +### `unique_crashes_panic_locations.rb` + +Summarize results from `collect_unique_crashes.rb`, only showing the location of +the crash. + +### `unique_crashes_representative_inputs.rb` + +Find representative inputs (along with their outputs) from `./unique_crashes` +and store them in `./unique_crash_location_representatives`. + +### `force_quit_fuzzing_job.rb` + +Force-quit the fuzzing runners and targets. + +## To reproduce a crash + +```bash +❯ cargo afl run ../../target/debug/ssa_afl_fuzzer < outputs/fuzzer01/crashes/id:000000,sig:06,src:001205,time:60283,execs:196992,op:quick,pos:1261 +``` diff --git a/tooling/ssa_afl_fuzzer/collect_outputs.rb b/tooling/ssa_afl_fuzzer/collect_outputs.rb new file mode 100755 index 00000000000..aa3c13eaa2d --- /dev/null +++ b/tooling/ssa_afl_fuzzer/collect_outputs.rb @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby + +require 'fileutils' + +output_dirs = [ + # TODO: re-enable? + # "outputs", + # "outputs2", + # "outputs3", + # "outputs8", + "outputs9", +] + +collected_output_dir = ARGV[0] +if collected_output_dir.nil? + raise "the first argument is required: [dir-for-all-outputs]" +end + +num_crashes = 0 +puts "copying crashing inputs to #{collected_output_dir}" + +# [output_dir]/[worker_dir]/crashes/id:[..] +output_dirs.each do |output_dir| + Dir["#{output_dir}/*"].filter do |worker_output_dir| + if Dir.exist? worker_output_dir + Dir["#{worker_output_dir}/crashes/id:*"].each do |crash_path| + puts "copying #{crash_path}" + FileUtils.cp crash_path, ARGV[0] + num_crashes += 1 + end + end + end +end + +puts "copied #{num_crashes} crashes." diff --git a/tooling/ssa_afl_fuzzer/collect_unique_crashes.rb b/tooling/ssa_afl_fuzzer/collect_unique_crashes.rb new file mode 100755 index 00000000000..e484badac3d --- /dev/null +++ b/tooling/ssa_afl_fuzzer/collect_unique_crashes.rb @@ -0,0 +1,105 @@ +#!/usr/bin/env ruby + +require 'fileutils' +require 'open3' +require 'timeout' + + +# TODO: timeout? this appears to have been caused by rebuilding 'ssa_afl_fuzzer' +# +# attempting reproduction on ./collected_outputs/id:000255,sig:09,src:003970,time:82662864,execs:226910830,op:colorization,rep:2 +# ^C# terminated with exception (report_on_exception is true): +# /usr/lib/ruby/3.2.0/open3.rb:404:in `read': stream closed in another thread (IOError) +# from /usr/lib/ruby/3.2.0/open3.rb:404:in `block (2 levels) in capture2e' +# /usr/lib/ruby/3.2.0/open3.rb:416:in `value': Interrupt +# from /usr/lib/ruby/3.2.0/open3.rb:416:in `block in capture2e' +# from /usr/lib/ruby/3.2.0/open3.rb:228:in `popen_run' +# from /usr/lib/ruby/3.2.0/open3.rb:210:in `popen2e' +# from /usr/lib/ruby/3.2.0/open3.rb:399:in `capture2e' +# from ./collect_unique_crashes.rb:11:in `run_nargo' +# from ./collect_unique_crashes.rb:37:in `block in
' +# from ./collect_unique_crashes.rb:35:in `map' +# from ./collect_unique_crashes.rb:35:in `
' + + +def run_nargo(program_path, program_str) + target_path = "../../target/debug/ssa_afl_fuzzer" + cmd_str = "cargo afl run #{target_path} < #{program_path}" + + stdout_and_stderr_str = nil + status = nil + # timeout after 5 seconds + begin + Timeout::timeout(5) do + # If opts[:stdin_data] is specified, it is sent to the command’s standard input. + stdout_and_stderr_str, status = Open3.capture2e(cmd_str) # , stdin_data: program_str) + end + rescue Timeout::Error => e + stdout_and_stderr_str = "#{e}" + end + + if !status.nil? && status.success? + puts "unexpected successful input: #{program_path}" + nil + else + stdout_and_stderr_str + end +end + +# make output dir's +unless Dir.exist? './collected_outputs' + FileUtils.mkdir './collected_outputs' +else + # clear previous results + Dir['./collected_outputs/*'].each do |collected_output| + FileUtils.rm_rf collected_output + end +end +unless Dir.exist? './unique_crashes' + FileUtils.mkdir './unique_crashes' +else + # clear previous results + Dir['./unique_crashes/*'].each do |unique_crash| + FileUtils.rm_rf unique_crash + end +end + +# update ./collected_outputs +system "./collect_outputs.rb ./collected_outputs" +puts + +# rebuild fuzz target (in case it updated) +system "cargo afl build" + +num_crashes = 0 +Dir['./collected_outputs/*'].map do |collected_output_path| + [collected_output_path, File.read(collected_output_path)] +end.flat_map do |collected_output_path, collected_output_str| + puts "attempting reproduction on #{collected_output_path}" + nargo_output = run_nargo collected_output_path, collected_output_str + if nargo_output.nil? + [] + else + [[collected_output_path, collected_output_str, nargo_output]] + end +end.group_by do |collected_output_path, collected_output_str, nargo_output| + nargo_output +end.map do |nargo_output, collected_outputs| + smallest_input_path_and_str = collected_outputs.min_by do |_, collected_output_str, _| + collected_output_str.length + end + puts "#{collected_outputs.length} non-unique crashes" + smallest_input_path = smallest_input_path_and_str[0] + smallest_input_str = smallest_input_path_and_str[1] + + puts "copying #{smallest_input_path.inspect}, (input size: #{smallest_input_str.length})" + FileUtils.cp smallest_input_path, './unique_crashes' + + smallest_input_basename = File.basename smallest_input_path + File.write "./unique_crashes/#{smallest_input_basename}.out", nargo_output + + num_crashes += 1 +end +puts + +puts "copied #{num_crashes} output-unique crashes." diff --git a/tooling/ssa_afl_fuzzer/combined_final.md b/tooling/ssa_afl_fuzzer/combined_final.md new file mode 100644 index 00000000000..931708c67a2 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/combined_final.md @@ -0,0 +1,324 @@ + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 6 sec │ cycles done : 189 │ +│ last new find : 0 days, 0 hrs, 4 min, 59 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 5 min, 10 sec │saved crashes : 323 │ +│ last saved hang : 0 days, 0 hrs, 8 min, 50 sec │ saved hangs : 95 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 12.3k.0 (100.0%) │ map density : 0.74% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 684 (5.56%) │ +│ stage execs : 53.8k/131k (40.97%) │ new edges on : 1077 (8.76%) │ +│ total execs : 39.2M │ total crashes : 5901 (323 saved) │ +│ exec speed : 172.1/sec │ total tmouts : 433 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/51.3k, 1/51.3k, 0/51.3k │ levels : 11 │ +│ byte flips : 0/6415, 0/6408, 0/6394 │ pending : 17 │ +│ arithmetics : 2/448k, 0/893k, 0/891k │ pend fav : 1 │ +│ known ints : 0/57.6k, 0/243k, 0/357k │ own finds : 1290 │ +│ dictionary : 0/0, 0/0, 2/4.06M, 0/4.07M │ imported : 2627 │ +│havoc/splice : 512/12.7M, 48/23.9M │ stability : 98.29% │ +│py/custom/rq : unused, unused, 1003/2.27M, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 99.58% │ [cpu000: 29%] +└─ strategy: explore ────────── state: in progress ──┘^C + + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 6 sec │ cycles done : 11 │ +│ last new find : 0 days, 0 hrs, 0 min, 27 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 3 min, 38 sec │saved crashes : 296 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 49 sec │ saved hangs : 80 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1596*6 (13.0%) │ map density : 1.13% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 15 │ favored items : 678 (5.51%) │ +│ stage execs : 2/12 (16.67%) │ new edges on : 1062 (8.64%) │ +│ total execs : 54.0M │ total crashes : 3335 (296 saved) │ +│ exec speed : 17.7k/sec │ total tmouts : 379 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 7/254k, 0/254k, 0/254k │ levels : 19 │ +│ byte flips : 0/31.8k, 4/31.8k, 0/31.8k │ pending : 3 │ +│ arithmetics : 6/2.23M, 0/4.44M, 0/4.43M │ pend fav : 0 │ +│ known ints : 0/285k, 1/1.21M, 0/1.78M │ own finds : 2064 │ +│ dictionary : 0/0, 0/0, 1/52.1M, 0/52.1M │ imported : 1846 │ +│havoc/splice : 1147/17.4M, 214/32.3M │ stability : 98.28% │ +│py/custom/rq : unused, unused, 887/1.28M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.89%/2.66M, 99.75% │ [cpu001: 28%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 6 sec │ cycles done : 10 │ +│ last new find : 0 days, 0 hrs, 0 min, 36 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 53 sec │saved crashes : 314 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 56 sec │ saved hangs : 81 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 8779.127 (71.3%) │ map density : 0.27% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 688 (5.59%) │ +│ stage execs : 65/75 (86.67%) │ new edges on : 1065 (8.65%) │ +│ total execs : 49.0M │ total crashes : 3274 (314 saved) │ +│ exec speed : 16.6k/sec │ total tmouts : 415 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 12/218k, 5/218k, 2/217k │ levels : 17 │ +│ byte flips : 0/27.3k, 2/27.2k, 0/27.2k │ pending : 6 │ +│ arithmetics : 9/1.91M, 0/3.80M, 0/3.79M │ pend fav : 0 │ +│ known ints : 0/244k, 0/1.03M, 0/1.52M │ own finds : 2046 │ +│ dictionary : 0/0, 0/0, 0/31.9M, 0/31.9M │ imported : 1887 │ +│havoc/splice : 1106/15.6M, 142/29.0M │ stability : 98.29% │ +│py/custom/rq : unused, unused, 966/1.30M, 0/0 ├───────────────────────┘ +│ trim/eff : 5.06%/2.61M, 99.67% │ [cpu005: 23%] +└─ strategy: explore ────────── state: in progress ──┘^C + + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 6 sec │ cycles done : 11 │ +│ last new find : 0 days, 0 hrs, 2 min, 19 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 15 sec │saved crashes : 324 │ +│ last saved hang : 0 days, 0 hrs, 5 min, 47 sec │ saved hangs : 86 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 9046.105 (73.7%) │ map density : 0.08% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 6 │ favored items : 686 (5.59%) │ +│ stage execs : 9/12 (75.00%) │ new edges on : 1071 (8.72%) │ +│ total execs : 52.7M │ total crashes : 3265 (324 saved) │ +│ exec speed : 18.1k/sec │ total tmouts : 315 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 10/239k, 0/239k, 1/239k │ levels : 18 │ +│ byte flips : 0/30.0k, 2/29.9k, 0/29.9k │ pending : 0 │ +│ arithmetics : 13/2.10M, 0/4.17M, 0/4.17M │ pend fav : 0 │ +│ known ints : 0/269k, 0/1.14M, 0/1.67M │ own finds : 2041 │ +│ dictionary : 0/0, 0/0, 7/41.6M, 0/41.6M │ imported : 1853 │ +│havoc/splice : 1128/16.8M, 129/31.5M │ stability : 98.27% │ +│py/custom/rq : unused, unused, 938/1.31M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.53%/2.64M, 99.59% │ [cpu006: 26%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer05} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 5 sec │ cycles done : 10 │ +│ last new find : 0 days, 0 hrs, 1 min, 18 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 28 sec │saved crashes : 308 │ +│ last saved hang : 0 days, 0 hrs, 1 min, 5 sec │ saved hangs : 87 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 11.3k.123 (91.5%) │ map density : 1.10% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 14 │ favored items : 690 (5.61%) │ +│ stage execs : 13/18 (72.22%) │ new edges on : 1066 (8.67%) │ +│ total execs : 48.4M │ total crashes : 3207 (308 saved) │ +│ exec speed : 17.8k/sec │ total tmouts : 447 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 12/108k, 7/108k, 1/108k │ levels : 22 │ +│ byte flips : 0/13.6k, 2/13.6k, 0/13.6k │ pending : 4 │ +│ arithmetics : 6/952k, 0/1.89M, 0/1.89M │ pend fav : 0 │ +│ known ints : 0/122k, 0/515k, 0/758k │ own finds : 2013 │ +│ dictionary : 0/0, 0/0, 2/8.93M, 0/8.94M │ imported : 1897 │ +│havoc/splice : 1047/15.3M, 149/28.8M │ stability : 98.28% │ +│py/custom/rq : unused, unused, 978/1.30M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.11%/2.61M, 99.27% │ [cpu007: 25%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer06} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 5 sec │ cycles done : 10 │ +│ last new find : 0 days, 0 hrs, 0 min, 10 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 9 sec │saved crashes : 323 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 15 sec │ saved hangs : 100 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 9544.148 (77.6%) │ map density : 1.29% / 3.76% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.74 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 6 │ favored items : 695 (5.65%) │ +│ stage execs : 33/37 (89.19%) │ new edges on : 1073 (8.72%) │ +│ total execs : 47.0M │ total crashes : 3479 (323 saved) │ +│ exec speed : 17.5k/sec │ total tmouts : 738 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 6/146k, 6/146k, 1/146k │ levels : 17 │ +│ byte flips : 0/18.3k, 3/18.3k, 1/18.2k │ pending : 6 │ +│ arithmetics : 9/1.28M, 0/2.54M, 0/2.54M │ pend fav : 0 │ +│ known ints : 0/164k, 0/692k, 0/1.02M │ own finds : 2073 │ +│ dictionary : 0/0, 0/0, 7/18.2M, 0/18.3M │ imported : 1849 │ +│havoc/splice : 1077/14.9M, 128/27.7M │ stability : 98.31% │ +│py/custom/rq : unused, unused, 1029/1.29M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.92%/2.63M, 99.39% │ [cpu008: 17%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer07} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 5 sec │ cycles done : 9 │ +│ last new find : 0 days, 0 hrs, 0 min, 5 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 0 sec │saved crashes : 319 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 38 sec │ saved hangs : 73 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 10.2k.131 (83.2%) │ map density : 1.42% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 691 (5.62%) │ +│ stage execs : 75/150 (50.00%) │ new edges on : 1060 (8.62%) │ +│ total execs : 45.7M │ total crashes : 3216 (319 saved) │ +│ exec speed : 17.7k/sec │ total tmouts : 656 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 5/142k, 7/142k, 0/142k │ levels : 19 │ +│ byte flips : 0/17.8k, 1/17.7k, 0/17.7k │ pending : 2 │ +│ arithmetics : 9/1.24M, 0/2.47M, 0/2.47M │ pend fav : 0 │ +│ known ints : 0/159k, 0/673k, 0/989k │ own finds : 2099 │ +│ dictionary : 0/0, 0/0, 8/18.1M, 0/18.1M │ imported : 1820 │ +│havoc/splice : 1012/14.5M, 282/26.9M │ stability : 98.27% │ +│py/custom/rq : unused, unused, 999/1.29M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.35%/2.65M, 99.58% │ [cpu009: 15%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer08} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 23 min, 5 sec │ cycles done : 10 │ +│ last new find : 0 days, 0 hrs, 1 min, 21 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 1 min, 28 sec │saved crashes : 316 │ +│ last saved hang : 0 days, 0 hrs, 2 min, 24 sec │ saved hangs : 81 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 11.4k.103 (92.8%) │ map density : 0.70% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 700 (5.70%) │ +│ stage execs : 130/300 (43.33%) │ new edges on : 1063 (8.66%) │ +│ total execs : 49.5M │ total crashes : 3335 (316 saved) │ +│ exec speed : 17.5k/sec │ total tmouts : 850 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 15/341k, 3/341k, 0/341k │ levels : 20 │ +│ byte flips : 0/42.7k, 4/42.6k, 0/42.6k │ pending : 3 │ +│ arithmetics : 5/2.98M, 0/5.95M, 0/5.94M │ pend fav : 0 │ +│ known ints : 0/383k, 0/1.62M, 0/2.38M │ own finds : 2188 │ +│ dictionary : 0/0, 0/0, 7/66.7M, 0/66.7M │ imported : 1703 │ +│havoc/splice : 1185/15.7M, 157/29.4M │ stability : 98.29% │ +│py/custom/rq : unused, unused, 966/1.34M, 0/0 ├───────────────────────┘ +│ trim/eff : 4.14%/2.61M, 99.70% │ [cpu010: 14%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer09} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 55 min, 23 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 0 min, 7 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 53 sec │saved crashes : 237 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 23 sec │ saved hangs : 62 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 8751.67 (71.3%) │ map density : 0.33% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 696 (5.67%) │ +│ stage execs : 58/150 (38.67%) │ new edges on : 1072 (8.73%) │ +│ total execs : 26.9M │ total crashes : 1950 (237 saved) │ +│ exec speed : 18.6k/sec │ total tmouts : 171 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/8016, 0/8014, 0/8010 │ levels : 5 │ +│ byte flips : 0/1002, 0/1000, 0/996 │ pending : 3 │ +│ arithmetics : 0/70.1k, 0/139k, 0/139k │ pend fav : 0 │ +│ known ints : 0/9010, 0/38.0k, 0/55.8k │ own finds : 277 │ +│ dictionary : 0/0, 0/0, 0/880k, 0/881k │ imported : 3614 │ +│havoc/splice : 231/7.83M, 68/15.3M │ stability : 98.24% │ +│py/custom/rq : unused, unused, 199/845k, 0/0 ├───────────────────────┘ +│ trim/eff : 3.89%/2.61M, 99.80% │ [cpu011: 10%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer10} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 55 min, 8 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 0 min, 9 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 0 min, 48 sec │saved crashes : 242 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 50 sec │ saved hangs : 54 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 12.3k.1 (100.0%) │ map density : 0.74% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : quick eff │ favored items : 695 (5.65%) │ +│ stage execs : 6544/65.5k (9.99%) │ new edges on : 1072 (8.71%) │ +│ total execs : 26.3M │ total crashes : 2006 (242 saved) │ +│ exec speed : 367.8/sec │ total tmouts : 168 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/102k, 0/102k, 0/102k │ levels : 4 │ +│ byte flips : 0/12.8k, 0/12.8k, 0/12.8k │ pending : 2 │ +│ arithmetics : 0/896k, 0/1.79M, 0/1.79M │ pend fav : 1 │ +│ known ints : 0/115k, 0/486k, 0/716k │ own finds : 229 │ +│ dictionary : 0/0, 0/0, 0/24.0M, 0/24.0M │ imported : 3693 │ +│havoc/splice : 225/7.63M, 21/14.9M │ stability : 98.29% │ +│py/custom/rq : unused, unused, 198/864k, 0/0 ├───────────────────────┘ +│ trim/eff : 3.89%/2.61M, 99.98% │ [cpu012: 14%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer11} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 54 min, 54 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 0 min, 3 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 1 min, 17 sec │saved crashes : 229 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 27 sec │ saved hangs : 55 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 9277.89 (75.5%) │ map density : 1.29% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.73 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 1 │ favored items : 694 (5.65%) │ +│ stage execs : 7/18 (38.89%) │ new edges on : 1078 (8.77%) │ +│ total execs : 27.2M │ total crashes : 1910 (229 saved) │ +│ exec speed : 18.1k/sec │ total tmouts : 178 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/47.9k, 0/47.9k, 0/47.9k │ levels : 4 │ +│ byte flips : 0/5984, 0/5983, 0/5981 │ pending : 6 │ +│ arithmetics : 0/418k, 0/837k, 0/837k │ pend fav : 0 │ +│ known ints : 0/53.9k, 0/227k, 0/334k │ own finds : 218 │ +│ dictionary : 0/0, 0/0, 0/11.2M, 0/11.2M │ imported : 3684 │ +│havoc/splice : 221/7.99M, 14/15.6M │ stability : 98.31% │ +│py/custom/rq : unused, unused, 193/844k, 0/0 ├───────────────────────┘ +│ trim/eff : 3.93%/2.57M, 99.98% │ [cpu013: 9%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer12} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 54 min, 48 sec │ cycles done : 5 │ +│ last new find : 0 days, 0 hrs, 2 min, 41 sec │ corpus count : 12.3k │ +│last saved crash : 0 days, 0 hrs, 1 min, 8 sec │saved crashes : 240 │ +│ last saved hang : 0 days, 0 hrs, 0 min, 1 sec │ saved hangs : 61 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 10.0k.56 (81.5%) │ map density : 1.58% / 3.75% │ +│ runs timed out : 0 (0.00%) │ count coverage : 4.74 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 3 │ favored items : 692 (5.63%) │ +│ stage execs : 4/14 (28.57%) │ new edges on : 1078 (8.77%) │ +│ total execs : 25.5M │ total crashes : 1887 (240 saved) │ +│ exec speed : 20.0k/sec │ total tmouts : 217 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/48.2k, 0/48.2k, 0/48.2k │ levels : 4 │ +│ byte flips : 0/6029, 0/6028, 0/6026 │ pending : 1 │ +│ arithmetics : 0/421k, 0/842k, 0/842k │ pend fav : 0 │ +│ known ints : 0/54.2k, 0/228k, 0/337k │ own finds : 223 │ +│ dictionary : 0/0, 0/0, 0/12.9M, 0/12.9M │ imported : 3690 │ +│havoc/splice : 223/7.37M, 16/14.4M │ stability : 98.24% │ +│py/custom/rq : unused, unused, 195/830k, 0/0 ├───────────────────────┘ +│ trim/eff : 3.85%/2.61M, 99.88% │ [cpu014: 7%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + diff --git a/tooling/ssa_afl_fuzzer/defunctionalize_final.md b/tooling/ssa_afl_fuzzer/defunctionalize_final.md new file mode 100644 index 00000000000..baeacd03732 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/defunctionalize_final.md @@ -0,0 +1,216 @@ + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 15 min, 20 sec │ cycles done : 662 │ +│ last new find : 0 days, 0 hrs, 9 min, 47 sec │ corpus count : 1459 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 759*26 (52.0%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 15 │ favored items : 136 (9.32%) │ +│ stage execs : 11/37 (29.73%) │ new edges on : 248 (17.00%) │ +│ total execs : 105M │ total crashes : 0 (0 saved) │ +│ exec speed : 23.9k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/784, 0/783, 0/781 │ levels : 9 │ +│ byte flips : 0/98, 0/97, 0/95 │ pending : 0 │ +│ arithmetics : 0/6846, 0/13.4k, 0/13.2k │ pend fav : 0 │ +│ known ints : 0/880, 0/3676, 0/5310 │ own finds : 497 │ +│ dictionary : 0/0, 0/0, 0/1960, 0/1980 │ imported : 228 │ +│havoc/splice : 382/37.3M, 85/67.6M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 29/172k, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 98.98% │ [cpu000: 4%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 15 min, 16 sec │ cycles done : 67 │ +│ last new find : 0 days, 0 hrs, 9 min, 21 sec │ corpus count : 1453 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1400*24 (96.4%) │ map density : 0.08% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 3 │ favored items : 142 (9.77%) │ +│ stage execs : 33/50 (66.00%) │ new edges on : 249 (17.14%) │ +│ total execs : 93.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 24.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 12/992, 3/990, 1/986 │ levels : 12 │ +│ byte flips : 0/124, 2/122, 0/118 │ pending : 0 │ +│ arithmetics : 10/8549, 0/15.8k, 0/15.3k │ pend fav : 0 │ +│ known ints : 2/1082, 3/4541, 0/6518 │ own finds : 490 │ +│ dictionary : 0/0, 0/0, 0/2432, 0/2462 │ imported : 229 │ +│havoc/splice : 347/33.6M, 80/59.6M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 21/255k, 0/0 ├───────────────────────┘ +│ trim/eff : 32.63%/63.7k, 92.74% │ [cpu001: 7%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 14 min, 54 sec │ cycles done : 85 │ +│ last new find : 0 days, 0 hrs, 9 min, 32 sec │ corpus count : 1446 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 886.704 (61.3%) │ map density : 0.09% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 7 │ favored items : 140 (9.68%) │ +│ stage execs : 13/37 (35.14%) │ new edges on : 253 (17.50%) │ +│ total execs : 100M │ total crashes : 0 (0 saved) │ +│ exec speed : 24.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 10 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 342 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 370 │ +│havoc/splice : 277/36.2M, 51/64.4M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 14/247k, 0/0 ├───────────────────────┘ +│ trim/eff : 29.56%/72.5k, n/a │ [cpu004: 14%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 14 min, 31 sec │ cycles done : 93 │ +│ last new find : 0 days, 0 hrs, 9 min, 49 sec │ corpus count : 1463 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1292.749 (88.3%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 146 (9.98%) │ +│ stage execs : 145/200 (72.50%) │ new edges on : 253 (17.29%) │ +│ total execs : 98.7M │ total crashes : 0 (0 saved) │ +│ exec speed : 24.1k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 4 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 198 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 531 │ +│havoc/splice : 169/35.3M, 18/63.0M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 11/254k, 0/0 ├───────────────────────┘ +│ trim/eff : 33.47%/59.5k, n/a │ [cpu005: 12%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer05} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 14 min, 1 sec │ cycles done : 95 │ +│ last new find : 0 days, 0 hrs, 9 min, 12 sec │ corpus count : 1475 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1168*45 (79.2%) │ map density : 0.07% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 147 (9.97%) │ +│ stage execs : 216/300 (72.00%) │ new edges on : 256 (17.36%) │ +│ total execs : 102M │ total crashes : 0 (0 saved) │ +│ exec speed : 23.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 15/256, 4/255, 1/253 │ levels : 4 │ +│ byte flips : 0/32, 3/31, 0/29 │ pending : 0 │ +│ arithmetics : 12/2123, 0/3254, 0/2940 │ pend fav : 0 │ +│ known ints : 2/257, 2/1095, 0/1544 │ own finds : 227 │ +│ dictionary : 0/0, 0/0, 0/126, 0/132 │ imported : 514 │ +│havoc/splice : 155/37.2M, 14/65.4M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 11/127k, 0/0 ├───────────────────────┘ +│ trim/eff : 32.38%/61.9k, 75.00% │ [cpu006: 12%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer06} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 13 min, 39 sec │ cycles done : 94 │ +│ last new find : 0 days, 0 hrs, 9 min, 39 sec │ corpus count : 1458 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1097.1036 (75.2%) │ map density : 0.18% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 5 │ favored items : 143 (9.81%) │ +│ stage execs : 22/37 (59.46%) │ new edges on : 250 (17.15%) │ +│ total execs : 102M │ total crashes : 0 (0 saved) │ +│ exec speed : 24.2k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 4 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 179 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 545 │ +│havoc/splice : 144/36.5M, 23/65.3M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 12/168k, 0/0 ├───────────────────────┘ +│ trim/eff : 29.26%/60.9k, n/a │ [cpu007: 20%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer07} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 13 min, 24 sec │ cycles done : 81 │ +│ last new find : 0 days, 0 hrs, 9 min, 2 sec │ corpus count : 1467 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1049.739 (71.5%) │ map density : 0.13% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 6 │ favored items : 145 (9.88%) │ +│ stage execs : 31/56 (55.36%) │ new edges on : 256 (17.45%) │ +│ total execs : 99.9M │ total crashes : 0 (0 saved) │ +│ exec speed : 23.4k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 4 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 173 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 560 │ +│havoc/splice : 154/35.4M, 6/64.3M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 13/175k, 0/0 ├───────────────────────┘ +│ trim/eff : 27.14%/58.7k, n/a │ [cpu008: 25%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer08} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 13 min, 15 sec │ cycles done : 83 │ +│ last new find : 0 days, 0 hrs, 9 min, 35 sec │ corpus count : 1457 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1449.523 (99.5%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 12 │ favored items : 146 (10.02%) │ +│ stage execs : 22/37 (59.46%) │ new edges on : 254 (17.43%) │ +│ total execs : 99.7M │ total crashes : 0 (0 saved) │ +│ exec speed : 23.4k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 3 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 158 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 565 │ +│havoc/splice : 132/35.4M, 15/64.1M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 11/159k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.52%/59.1k, n/a │ [cpu009: 23%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + diff --git a/tooling/ssa_afl_fuzzer/force_quit_fuzzing_job.rb b/tooling/ssa_afl_fuzzer/force_quit_fuzzing_job.rb new file mode 100755 index 00000000000..97cc937babb --- /dev/null +++ b/tooling/ssa_afl_fuzzer/force_quit_fuzzing_job.rb @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +# drop header line +`ps -ef`.lines.drop(1).map do |ps_line| + ps_columns = ps_line.split(' '); + [ps_columns[-1], ps_columns[1]] +end.select do |process_name, pid| + process_name.match?(/afl-fuzz/) || process_name.match?(/ssa_afl_fuzzer/) +end.each do |process_name, pid| + puts "kill -9 #{pid} # #{process_name}" + system("kill -9 #{pid}") +end + diff --git a/tooling/ssa_afl_fuzzer/inline_simple_before_params.md b/tooling/ssa_afl_fuzzer/inline_simple_before_params.md new file mode 100644 index 00000000000..f083c84ac05 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/inline_simple_before_params.md @@ -0,0 +1,293 @@ + +```bash + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 49 min, 46 sec │ cycles done : 332 │ +│ last new find : 0 days, 0 hrs, 3 min, 50 sec │ corpus count : 7465 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7267*11 (97.3%) │ map density : 0.10% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 142 (1.90%) │ +│ stage execs : 53/300 (17.67%) │ new edges on : 251 (3.36%) │ +│ total execs : 70.0M │ total crashes : 0 (0 saved) │ +│ exec speed : 23.9k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/600, 0/599, 0/597 │ levels : 15 │ +│ byte flips : 0/75, 0/74, 0/72 │ pending : 0 │ +│ arithmetics : 0/5235, 0/10.2k, 0/9940 │ pend fav : 0 │ +│ known ints : 0/672, 0/2802, 0/4022 │ own finds : 554 │ +│ dictionary : 0/0, 0/0, 0/750, 0/760 │ imported : 170 │ +│havoc/splice : 451/24.9M, 81/44.9M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 21/15.8k, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 98.67% │ [cpu000: 28%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 49 min, 28 sec │ cycles done : 7 │ +│ last new find : 0 days, 0 hrs, 3 min, 28 sec │ corpus count : 7465 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7177.351 (96.1%) │ map density : 0.13% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 13 │ favored items : 150 (2.01%) │ +│ stage execs : 59/112 (52.68%) │ new edges on : 257 (3.44%) │ +│ total execs : 60.1M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.2k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 12/96, 3/95, 2/93 │ levels : 10 │ +│ byte flips : 0/12, 1/11, 0/9 │ pending : 0 │ +│ arithmetics : 9/782, 0/989, 0/700 │ pend fav : 0 │ +│ known ints : 1/88, 2/375, 0/464 │ own finds : 440 │ +│ dictionary : 0/0, 0/0, 0/48, 0/52 │ imported : 284 │ +│havoc/splice : 342/21.6M, 59/38.3M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 5/54.2k, 0/0 ├───────────────────────┘ +│ trim/eff : 46.71%/62.1k, 66.67% │ [cpu001: 25%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 49 min, 3 sec │ cycles done : 7 │ +│ last new find : 0 days, 0 hrs, 3 min, 54 sec │ corpus count : 7470 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7440.187 (99.6%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 2 │ favored items : 159 (2.13%) │ +│ stage execs : 21/37 (56.76%) │ new edges on : 255 (3.41%) │ +│ total execs : 60.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.4k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 6/408, 4/406, 4/402 │ levels : 16 │ +│ byte flips : 0/51, 0/49, 0/45 │ pending : 0 │ +│ arithmetics : 6/3500, 0/6191, 0/5740 │ pend fav : 0 │ +│ known ints : 0/440, 2/1810, 0/2480 │ own finds : 385 │ +│ dictionary : 0/0, 0/0, 0/1604, 0/1652 │ imported : 344 │ +│havoc/splice : 293/21.6M, 61/38.8M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 4/46.3k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.45%/65.1k, 90.20% │ [cpu002: 23%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 49 min, 1 sec │ cycles done : 8 │ +│ last new find : 0 days, 0 hrs, 1 min, 13 sec │ corpus count : 7464 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7208.406 (96.6%) │ map density : 0.15% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 2 │ favored items : 154 (2.06%) │ +│ stage execs : 47/168 (27.98%) │ new edges on : 251 (3.36%) │ +│ total execs : 62.1M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.6k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/440, 0/439, 0/437 │ levels : 18 │ +│ byte flips : 0/55, 0/54, 0/52 │ pending : 0 │ +│ arithmetics : 0/3808, 0/7140, 0/6860 │ pend fav : 0 │ +│ known ints : 0/487, 0/2022, 0/2882 │ own finds : 332 │ +│ dictionary : 0/0, 0/0, 0/1320, 0/1344 │ imported : 391 │ +│havoc/splice : 271/22.2M, 45/39.7M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 13/56.2k, 0/0 ├───────────────────────┘ +│ trim/eff : 47.80%/65.9k, 94.55% │ [cpu003: 21%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer05} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 46 min, 55 sec │ cycles done : 8 │ +│ last new find : 0 days, 0 hrs, 4 min, 57 sec │ corpus count : 7456 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6819.380 (91.5%) │ map density : 0.07% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 148 (1.98%) │ +│ stage execs : 9/300 (3.00%) │ new edges on : 254 (3.41%) │ +│ total execs : 58.9M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 3 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 149 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 566 │ +│havoc/splice : 126/21.0M, 8/37.7M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 15/53.4k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.51%/65.7k, n/a │ [cpu004: 64%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer06} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 46 min, 29 sec │ cycles done : 8 │ +│ last new find : 0 days, 0 hrs, 1 min, 52 sec │ corpus count : 7476 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7233.355 (96.7%) │ map density : 0.08% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 8 │ favored items : 157 (2.10%) │ +│ stage execs : 8/37 (21.62%) │ new edges on : 260 (3.48%) │ +│ total execs : 55.6M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.4k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 7 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 209 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 526 │ +│havoc/splice : 177/20.0M, 29/35.4M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 3/57.3k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.84%/64.4k, n/a │ [cpu005: 17%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer07} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 32 min, 2 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 0 min, 16 sec │ corpus count : 7467 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6938.218 (92.9%) │ map density : 0.10% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 9 │ favored items : 150 (2.01%) │ +│ stage execs : 17/37 (45.95%) │ new edges on : 249 (3.33%) │ +│ total execs : 40.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 3 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 141 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 585 │ +│havoc/splice : 129/14.4M, 1/26.0M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 11/42.5k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.47%/65.9k, n/a │ [cpu006: 51%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer08} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 31 min, 51 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 3 min, 40 sec │ corpus count : 7465 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6772*15 (90.7%) │ map density : 0.08% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 10 │ favored items : 152 (2.04%) │ +│ stage execs : 5/37 (13.51%) │ new edges on : 252 (3.38%) │ +│ total execs : 40.4M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.8k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 2 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 137 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 587 │ +│havoc/splice : 125/14.4M, 1/25.8M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 11/50.0k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.33%/65.9k, n/a │ [cpu007: 10%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer09} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 29 min, 34 sec │ cycles done : 5 │ +│ last new find : 0 days, 0 hrs, 2 min, 56 sec │ corpus count : 7465 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6965.196 (93.3%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 3 │ favored items : 146 (1.96%) │ +│ stage execs : 22/37 (59.46%) │ new edges on : 256 (3.43%) │ +│ total execs : 36.7M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.3k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 3 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 138 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 586 │ +│havoc/splice : 124/13.2M, 2/23.3M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 12/50.9k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.31%/66.0k, n/a │ [cpu008: 7%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +```bash + AFL ++4.21c {fuzzer10} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 0 hrs, 29 min, 25 sec │ cycles done : 5 │ +│ last new find : 0 days, 0 hrs, 1 min, 51 sec │ corpus count : 7472 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7069*15 (94.6%) │ map density : 0.13% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.39 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 155 (2.07%) │ +│ stage execs : 217/450 (48.22%) │ new edges on : 258 (3.45%) │ +│ total execs : 35.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 21.4k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 3 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 157 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 574 │ +│havoc/splice : 143/12.7M, 2/22.7M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 12/52.3k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.42%/65.3k, n/a │ [cpu009: 3%] +│ trim/eff : 45.42%/65.3k, n/a │ [cpu009: 10%] +└─ strategy: explore ────────── state: in progress ──┘ + ++++ Testing aborted by user +++ +``` + diff --git a/tooling/ssa_afl_fuzzer/keep_inputs_upto_2kb.rb b/tooling/ssa_afl_fuzzer/keep_inputs_upto_2kb.rb new file mode 100755 index 00000000000..c91fec6a8ca --- /dev/null +++ b/tooling/ssa_afl_fuzzer/keep_inputs_upto_2kb.rb @@ -0,0 +1,20 @@ +#!/bin/env ruby + +require 'fileutils' + +input_dirs = [ + 'defunctionalize_inputs', + 'inline_simple_inputs', + 'remove_unreachable_functions_inputs', +] + +num_removed = 0 +Dir['./defunctionalize_inputs/*.ssa'].each do |input_path| + if File.read(input_path).length > 2048 + puts "removing #{input_path}" + FileUtils.rm input_path + num_removed += 1 + end +end + +puts "removed #{num_removed} files" diff --git a/tooling/ssa_afl_fuzzer/make_combined_inputs.rb b/tooling/ssa_afl_fuzzer/make_combined_inputs.rb new file mode 100755 index 00000000000..a345ea5396b --- /dev/null +++ b/tooling/ssa_afl_fuzzer/make_combined_inputs.rb @@ -0,0 +1,28 @@ +#!/bin/env ruby + +require 'fileutils' +require 'pathname' + +input_dirs = [ + 'remove_unreachable_functions_inputs', + 'defunctionalize_inputs', + 'inline_simple_inputs', +] + +unless Dir.exist? './combined_inputs/' + FileUtils.mkdir './combined_inputs' +end + +Dir["./combined_inputs/*.ssa"].each do |combined_input_path| + FileUtils.rm_f combined_input_path +end + +input_dirs.each_with_index do |input_dir, input_dir_index| + Dir["./#{input_dir}/*.ssa"].each do |input_ssa| + new_path = Pathname.new('./combined_inputs') + Pathname.new(input_ssa).basename + pow2_index = 2 ** input_dir_index + new_contents = "// #{pow2_index}\n" + File.read(input_ssa) + puts "copying to #{new_path}" + File.write(new_path, new_contents) + end +end diff --git a/tooling/ssa_afl_fuzzer/remove_unreachable_functions_final.md b/tooling/ssa_afl_fuzzer/remove_unreachable_functions_final.md new file mode 100644 index 00000000000..67effbce87b --- /dev/null +++ b/tooling/ssa_afl_fuzzer/remove_unreachable_functions_final.md @@ -0,0 +1,125 @@ + +Worker 1: + +```bash + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 8 min, 44 sec │ cycles done : 486 │ +│ last new find : 0 days, 0 hrs, 9 min, 24 sec │ corpus count : 1573 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1247*20 (79.3%) │ map density : 0.13% / 0.42% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.38 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 12 │ favored items : 124 (7.88%) │ +│ stage execs : 3/37 (8.11%) │ new edges on : 222 (14.11%) │ +│ total execs : 79.3M │ total crashes : 0 (0 saved) │ +│ exec speed : 22.7k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/19.2k, 0/19.2k, 0/19.2k │ levels : 13 │ +│ byte flips : 0/2406, 0/2403, 0/2397 │ pending : 0 │ +│ arithmetics : 1/168k, 0/336k, 0/335k │ pend fav : 0 │ +│ known ints : 0/21.6k, 0/91.3k, 0/134k │ own finds : 427 │ +│ dictionary : 0/0, 0/0, 0/24.1k, 0/24.1k │ imported : 237 │ +│havoc/splice : 288/28.3M, 81/50.6M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 54/353k, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 99.88% │ [cpu000: 15%] +└─ strategy: explore ────────── state: in progress ──┘^C[110;10u + ++++ Testing aborted by user +++ +``` + +Worker 2: + +```bash + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 8 min, 30 sec │ cycles done : 42 │ +│ last new find : 0 days, 0 hrs, 9 min, 51 sec │ corpus count : 1584 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1269.593 (80.1%) │ map density : 0.08% / 0.42% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.38 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 9 │ favored items : 128 (8.08%) │ +│ stage execs : 72/75 (96.00%) │ new edges on : 225 (14.20%) │ +│ total execs : 68.0M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.9k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/992, 0/990, 0/986 │ levels : 10 │ +│ byte flips : 0/124, 0/122, 0/118 │ pending : 0 │ +│ arithmetics : 0/8652, 0/16.8k, 0/16.2k │ pend fav : 0 │ +│ known ints : 0/1109, 0/4616, 0/6588 │ own finds : 429 │ +│ dictionary : 0/0, 0/0, 0/2804, 0/2872 │ imported : 246 │ +│havoc/splice : 347/24.6M, 71/43.0M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 9/292k, 0/0 ├───────────────────────┘ +│ trim/eff : 38.08%/78.3k, 98.39% │ [cpu001: 9%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +Worker 3: + +```bash + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 8 min, 23 sec │ cycles done : 41 │ +│ last new find : 0 days, 0 hrs, 9 min, 7 sec │ corpus count : 1576 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1448.323 (91.9%) │ map density : 0.11% / 0.42% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.38 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 2 │ favored items : 135 (8.57%) │ +│ stage execs : 27/37 (72.97%) │ new edges on : 225 (14.28%) │ +│ total execs : 65.0M │ total crashes : 0 (0 saved) │ +│ exec speed : 18.6k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/904, 0/901, 0/895 │ levels : 10 │ +│ byte flips : 0/113, 0/110, 0/104 │ pending : 0 │ +│ arithmetics : 0/7868, 0/15.0k, 0/14.1k │ pend fav : 0 │ +│ known ints : 0/1005, 0/4150, 0/5794 │ own finds : 413 │ +│ dictionary : 0/0, 0/0, 0/3974, 0/4083 │ imported : 254 │ +│havoc/splice : 340/23.3M, 49/41.3M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 21/314k, 0/0 ├───────────────────────┘ +│ trim/eff : 41.18%/74.2k, 97.35% │ [cpu002: 9%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + +Worker 4: + +```bash + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 8 min, 9 sec │ cycles done : 44 │ +│ last new find : 0 days, 0 hrs, 8 min, 43 sec │ corpus count : 1568 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 1368.370 (87.2%) │ map density : 0.10% / 0.42% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.38 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 8 │ favored items : 132 (8.42%) │ +│ stage execs : 24/37 (64.86%) │ new edges on : 222 (14.16%) │ +│ total execs : 71.2M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.1k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/208, 0/207, 0/205 │ levels : 12 │ +│ byte flips : 0/26, 0/25, 0/23 │ pending : 0 │ +│ arithmetics : 0/1806, 0/3360, 0/3080 │ pend fav : 0 │ +│ known ints : 0/232, 0/940, 0/1278 │ own finds : 362 │ +│ dictionary : 0/0, 0/0, 0/832, 0/864 │ imported : 297 │ +│havoc/splice : 293/25.4M, 50/45.6M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 18/160k, 0/0 ├───────────────────────┘ +│ trim/eff : 49.41%/71.3k, 96.15% │ [cpu003: 4%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ +``` + diff --git a/tooling/ssa_afl_fuzzer/run_with_parameters_final.md b/tooling/ssa_afl_fuzzer/run_with_parameters_final.md new file mode 100644 index 00000000000..ce799357a12 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/run_with_parameters_final.md @@ -0,0 +1,272 @@ + + AFL ++4.21c {fuzzer01} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 49 sec │ cycles done : 480 │ +│ last new find : 0 days, 0 hrs, 7 min, 22 sec │ corpus count : 7502 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6764*26 (90.2%) │ map density : 0.07% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : colorization │ favored items : 141 (1.88%) │ +│ stage execs : 839/1398 (60.01%) │ new edges on : 266 (3.55%) │ +│ total execs : 78.4M │ total crashes : 0 (0 saved) │ +│ exec speed : 1793/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 3/5592, 3/5591, 2/5589 │ levels : 9 │ +│ byte flips : 0/699, 1/698, 0/696 │ pending : 0 │ +│ arithmetics : 5/48.9k, 0/97.6k, 0/97.3k │ pend fav : 0 │ +│ known ints : 0/6285, 1/26.5k, 0/39.0k │ own finds : 192 │ +│ dictionary : 0/0, 0/0, 0/2796, 0/2800 │ imported : 569 │ +│havoc/splice : 150/28.0M, 18/50.1M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 7/244k, 0/0 ├───────────────────────┘ +│ trim/eff : disabled, 99.86% │ [cpu000: 28%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + + AFL ++4.21c {fuzzer02} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 44 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 9 min, 20 sec │ corpus count : 7521 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6940*21 (92.3%) │ map density : 0.07% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.61 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 3 │ favored items : 149 (1.98%) │ +│ stage execs : 2/75 (2.67%) │ new edges on : 264 (3.51%) │ +│ total execs : 80.7M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.6k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 8/448, 6/446, 2/442 │ levels : 14 │ +│ byte flips : 0/56, 0/54, 0/50 │ pending : 0 │ +│ arithmetics : 10/3835, 0/6754, 0/6160 │ pend fav : 0 │ +│ known ints : 1/482, 2/1989, 0/2740 │ own finds : 648 │ +│ dictionary : 0/0, 0/0, 0/660, 0/682 │ imported : 132 │ +│havoc/splice : 498/28.7M, 106/51.8M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 9/66.9k, 0/0 ├───────────────────────┘ +│ trim/eff : 44.42%/69.2k, 89.29% │ [cpu001: 26%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer03} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 40 sec │ cycles done : 7 │ +│ last new find : 0 days, 0 hrs, 1 min, 16 sec │ corpus count : 7491 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7033.415 (93.9%) │ map density : 0.15% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 5 │ favored items : 148 (1.98%) │ +│ stage execs : 43/112 (38.39%) │ new edges on : 261 (3.48%) │ +│ total execs : 79.8M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.6k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 2/280, 1/278, 0/274 │ levels : 13 │ +│ byte flips : 0/35, 0/33, 0/29 │ pending : 0 │ +│ arithmetics : 0/2408, 0/4243, 0/3640 │ pend fav : 0 │ +│ known ints : 0/306, 0/1224, 0/1594 │ own finds : 623 │ +│ dictionary : 0/0, 0/0, 0/420, 0/442 │ imported : 127 │ +│havoc/splice : 472/28.4M, 131/51.2M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 14/59.0k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.44%/67.4k, 91.43% │ [cpu004: 25%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer04} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 36 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 6 min, 4 sec │ corpus count : 7474 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7277.252 (97.4%) │ map density : 0.10% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 14 │ favored items : 146 (1.95%) │ +│ stage execs : 27/75 (36.00%) │ new edges on : 261 (3.49%) │ +│ total execs : 78.4M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.1k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/968, 0/965, 0/959 │ levels : 15 │ +│ byte flips : 0/121, 0/118, 0/112 │ pending : 0 │ +│ arithmetics : 0/8428, 0/16.1k, 0/15.5k │ pend fav : 0 │ +│ known ints : 0/1076, 1/4454, 0/6262 │ own finds : 601 │ +│ dictionary : 0/0, 0/0, 0/2790, 0/2936 │ imported : 132 │ +│havoc/splice : 461/28.2M, 112/50.0M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 24/63.7k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.95%/67.8k, 97.52% │ [cpu005: 21%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer05} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 31 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 0 min, 18 sec │ corpus count : 7489 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6916.212 (92.3%) │ map density : 0.08% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 13 │ favored items : 148 (1.98%) │ +│ stage execs : 41/75 (54.67%) │ new edges on : 253 (3.38%) │ +│ total execs : 82.8M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.5k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/0, 0/0, 0/0 │ levels : 15 │ +│ byte flips : 0/0, 0/0, 0/0 │ pending : 0 │ +│ arithmetics : 0/0, 0/0, 0/0 │ pend fav : 0 │ +│ known ints : 0/0, 0/0, 0/0 │ own finds : 627 │ +│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 121 │ +│havoc/splice : 515/30.1M, 93/52.5M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 19/66.6k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.19%/69.0k, n/a │ [cpu006: 15%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer06} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 27 sec │ cycles done : 7 │ +│ last new find : 0 days, 0 hrs, 0 min, 49 sec │ corpus count : 7491 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7200.365 (96.1%) │ map density : 0.15% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 6 │ favored items : 146 (1.95%) │ +│ stage execs : 32/56 (57.14%) │ new edges on : 259 (3.46%) │ +│ total execs : 78.8M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.8k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/1152, 0/1149, 0/1143 │ levels : 13 │ +│ byte flips : 0/144, 0/141, 0/135 │ pending : 0 │ +│ arithmetics : 0/10.0k, 0/19.2k, 0/18.6k │ pend fav : 0 │ +│ known ints : 0/1283, 1/5317, 0/7540 │ own finds : 613 │ +│ dictionary : 0/0, 0/0, 1/5752, 0/6006 │ imported : 137 │ +│havoc/splice : 482/27.9M, 105/50.7M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 20/69.1k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.27%/67.3k, 97.22% │ [cpu007: 17%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer07} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 21 sec │ cycles done : 6 │ +│ last new find : 0 days, 0 hrs, 7 min, 0 sec │ corpus count : 7490 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7177.390 (95.8%) │ map density : 0.12% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : havoc │ favored items : 151 (2.02%) │ +│ stage execs : 1159/1350 (85.85%) │ new edges on : 263 (3.51%) │ +│ total execs : 78.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 19.1k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/1232, 0/1229, 0/1223 │ levels : 16 │ +│ byte flips : 0/154, 0/151, 0/145 │ pending : 0 │ +│ arithmetics : 0/10.6k, 0/19.7k, 0/18.9k │ pend fav : 0 │ +│ known ints : 0/1355, 0/5638, 0/8020 │ own finds : 628 │ +│ dictionary : 0/0, 0/0, 1/8444, 0/8602 │ imported : 121 │ +│havoc/splice : 505/27.9M, 100/50.4M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 12/72.7k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.19%/65.9k, 93.51% │ [cpu008: 21%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer08} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 17 sec │ cycles done : 8 │ +│ last new find : 0 days, 0 hrs, 5 min, 44 sec │ corpus count : 7498 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7113.386 (94.9%) │ map density : 0.12% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 11 │ favored items : 154 (2.05%) │ +│ stage execs : 22/112 (19.64%) │ new edges on : 260 (3.47%) │ +│ total execs : 78.2M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.0k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 1/224, 0/223, 0/221 │ levels : 13 │ +│ byte flips : 0/28, 0/27, 0/25 │ pending : 0 │ +│ arithmetics : 0/1904, 0/3220, 0/2940 │ pend fav : 0 │ +│ known ints : 0/236, 2/986, 0/1360 │ own finds : 444 │ +│ dictionary : 0/0, 0/0, 3/1652, 0/1711 │ imported : 313 │ +│havoc/splice : 341/28.0M, 85/50.1M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 8/62.5k, 0/0 ├───────────────────────┘ +│ trim/eff : 44.42%/66.8k, 85.71% │ [cpu009: 10%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer09} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 13 sec │ cycles done : 8 │ +│ last new find : 0 days, 0 hrs, 4 min, 59 sec │ corpus count : 7488 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 7305.345 (97.6%) │ map density : 0.11% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 15 │ favored items : 148 (1.98%) │ +│ stage execs : 89/112 (79.46%) │ new edges on : 259 (3.46%) │ +│ total execs : 80.4M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.6k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 0/2440, 0/2438, 0/2434 │ levels : 12 │ +│ byte flips : 0/305, 0/303, 0/299 │ pending : 0 │ +│ arithmetics : 0/21.2k, 0/41.0k, 0/40.6k │ pend fav : 0 │ +│ known ints : 0/2717, 1/11.4k, 0/16.7k │ own finds : 423 │ +│ dictionary : 0/0, 0/0, 0/20.6k, 0/20.9k │ imported : 324 │ +│havoc/splice : 321/28.9M, 87/51.4M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 4/65.7k, 0/0 ├───────────────────────┘ +│ trim/eff : 45.55%/66.6k, 96.72% │ [cpu010: 7%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + + AFL ++4.21c {fuzzer10} (../../target/debug/ssa_afl_fuzzer) [explore] +┌─ process timing ────────────────────────────────────┬─ overall results ────┐ +│ run time : 0 days, 1 hrs, 7 min, 8 sec │ cycles done : 9 │ +│ last new find : 0 days, 0 hrs, 6 min, 16 sec │ corpus count : 7476 │ +│last saved crash : none seen yet │saved crashes : 0 │ +│ last saved hang : none seen yet │ saved hangs : 0 │ +├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ +│ now processing : 6991.560 (93.5%) │ map density : 0.10% / 0.43% │ +│ runs timed out : 0 (0.00%) │ count coverage : 2.62 bits/tuple │ +├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ +│ now trying : splice 5 │ favored items : 150 (2.01%) │ +│ stage execs : 11/37 (29.73%) │ new edges on : 258 (3.45%) │ +│ total execs : 78.5M │ total crashes : 0 (0 saved) │ +│ exec speed : 20.7k/sec │ total tmouts : 0 (0 saved) │ +├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ +│ bit flips : 7/192, 3/190, 4/186 │ levels : 11 │ +│ byte flips : 0/24, 1/22, 0/18 │ pending : 0 │ +│ arithmetics : 9/1565, 0/1969, 0/1540 │ pend fav : 0 │ +│ known ints : 1/182, 3/752, 0/938 │ own finds : 385 │ +│ dictionary : 0/0, 0/0, 0/460, 0/545 │ imported : 350 │ +│havoc/splice : 287/28.3M, 56/50.0M │ stability : 100.00% │ +│py/custom/rq : unused, unused, 6/59.7k, 0/0 ├───────────────────────┘ +│ trim/eff : 46.12%/64.7k, 66.67% │ [cpu011: 4%] +└─ strategy: explore ────────── state: in progress ──┘^C + ++++ Testing aborted by user +++ + diff --git a/tooling/ssa_afl_fuzzer/src/main.rs b/tooling/ssa_afl_fuzzer/src/main.rs new file mode 100644 index 00000000000..03c4ebb2df6 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/src/main.rs @@ -0,0 +1,78 @@ +#[macro_use] +extern crate afl; +extern crate noirc_evaluator; + +use std::str::FromStr; + +use noirc_evaluator::ssa::interpreter::value::Value; +use noirc_evaluator::ssa::ssa_gen::Ssa; + +fn main() { + fuzz!(|data: &[u8]| { + if let Ok(src) = std::str::from_utf8(data) { + if let Ok(ssa) = Ssa::from_str(src) { + // re-parsing is easier than cloning + let mut other_ssa = Ssa::from_str(src).expect("expected repeated SSA parsing to succeed"); + + let src_header_byte = if let Some(src_with_header) = src.strip_prefix("// ") { + if let Some(src_header_char) = src_with_header.chars().next() { + u32::from(src_header_char) + } else { + // enable no passes (empty file) + 0 + } + } else { + // enable all passes + 1 + 2 + 4 + }; + + // if first bit is set, 'remove_unreachable_functions' + if src_header_byte % 2 == 1 { + other_ssa = other_ssa.remove_unreachable_functions(); + } + // if second bit is set, 'inline_functions_with_at_most_one_instruction' + if (src_header_byte / 2) % 2 == 1 { + other_ssa = other_ssa.inline_functions_with_at_most_one_instruction(); + } + // if third bit is set, 'defunctionalize' + if (src_header_byte / 4) % 2 == 1 { + other_ssa = other_ssa.defunctionalize(); + } + + let main_fn = ssa.main(); + let parameter_ids = main_fn.parameters(); + let parameter_types = main_fn.signature().params; + assert_eq!(parameter_ids.len(), parameter_types.len()); + + let parameters: Vec<_> = parameter_types.iter().zip(parameter_ids).map(|(param_typ, param_id)| { + Value::uninitialized(param_typ, *param_id) + }).collect(); + let other_parameters: Vec<_> = parameter_types.iter().zip(parameter_ids).map(|(param_typ, param_id)| { + Value::uninitialized(param_typ, *param_id) + }).collect(); + + let result = ssa.interpret(parameters.clone()); + let other_result = other_ssa.interpret(other_parameters); + + // ensure both pass with the same result or both fail with the same error variant + match (result, other_result) { + (Ok(result_ok), Ok(other_result_ok)) => { + assert_eq!(result_ok, other_result_ok); + } + // check that the errors have the same discriminant (i.e. same enum variant) + (Err(err), Err(other_err)) => { + let disciminant = std::mem::discriminant(&err); + let other_disciminant = std::mem::discriminant(&other_err); + if disciminant != other_disciminant { + dbg!(&err, &other_err); + panic!("interpreter produced different errors") + } + } + (result, other_result) => { + panic!("results did not match when applying 'remove_unreachable_functions'!\n{:?}\n-----------\n{:?}", result, other_result) + } + } + } + } + }); +} diff --git a/tooling/ssa_afl_fuzzer/unique_crashes_panic_locations.rb b/tooling/ssa_afl_fuzzer/unique_crashes_panic_locations.rb new file mode 100755 index 00000000000..d9e6de9bf7e --- /dev/null +++ b/tooling/ssa_afl_fuzzer/unique_crashes_panic_locations.rb @@ -0,0 +1,13 @@ +#!/bin/env ruby + +# this script prints the unique locations where crashes occur + +Dir['unique_crashes/*.out'].flat_map do |unique_crash_path| + File.read(unique_crash_path).lines.flat_map do |unique_crash_line| + unique_crash_line.match(/thread 'main' panicked at (?.*):$/) || [] + end.map do |matched_line| + matched_line['unique_panic_location'] + end +end.sort.uniq.each do |unique_panic_location| + puts unique_panic_location +end diff --git a/tooling/ssa_afl_fuzzer/unique_crashes_representative_inputs.rb b/tooling/ssa_afl_fuzzer/unique_crashes_representative_inputs.rb new file mode 100755 index 00000000000..a129f5f6977 --- /dev/null +++ b/tooling/ssa_afl_fuzzer/unique_crashes_representative_inputs.rb @@ -0,0 +1,56 @@ +#!/bin/env ruby + +require 'fileutils' + +# this script finds unique locations where crashes occur and +# copies the smallest input file (along with its output) +# to './unique_crash_location_representatives/' + +unique_crash_path_and_locations = Dir['unique_crashes/*.out'].flat_map do |unique_crash_path| + File.read(unique_crash_path).lines.flat_map do |unique_crash_line| + unique_crash_line.match(/thread 'main' panicked at (?.*):$/) || [] + end.map do |matched_line| + matched_line['unique_panic_location'] + end.map do |unique_panic_location| + [unique_crash_path, unique_panic_location] + end +end + +# just the locations +unique_panic_locations = unique_crash_path_and_locations.map do |path, panic_location| + panic_location +end.sort.uniq + +unless Dir.exist? './unique_crash_location_representatives' + FileUtils.mkdir './unique_crash_location_representatives' +end + +# cleanup previous results +Dir['./unique_crash_location_representatives/*'].each do |unique_crash_location_representative| + FileUtils.rm_rf unique_crash_location_representative +end + +unique_panic_locations.each do |unique_panic_location| + smallest_representative_output = unique_crash_path_and_locations.select do |path, panic_location| + panic_location == unique_panic_location + end.sort_by do |output_path, panic_location| + input_path = output_path.sub '.out', '' + File.read(input_path).length + end.map do |output_path, panic_location| + output_path + end.first + + smallest_representative_input = smallest_representative_output.sub '.out', '' + + puts "#{unique_panic_location} has: \n#{smallest_representative_input}" + target_input_filename = unique_panic_location.gsub('/', '__').tr(':', '_') + '.ssa' + target_output_filename = target_input_filename.sub '.ssa', '.out' + + puts "copying #{smallest_representative_input} to ./unique_crash_location_representatives/#{target_input_filename}" + FileUtils.cp smallest_representative_input, "./unique_crash_location_representatives/#{target_input_filename}" + + puts "copying #{smallest_representative_output} to ./unique_crash_location_representatives/#{target_output_filename}" + FileUtils.cp smallest_representative_output, "./unique_crash_location_representatives/#{target_output_filename}" + + puts "#{'-' * 80}" +end