def test_set_stats_invalid_file(self): """Tests that all stats are set properly by set_stats() when stats_getter is *not* given a valid fuzzer_stats file. """ expected_stats = { 'actual_duration': 5, 'average_exec_per_sec': 0, 'bad_instrumentation': 0, 'corpus_crash_count': 0, 'corpus_size': 20, 'crash_count': 0, 'dict_used': 1, 'log_lines_unwanted': 0, 'manual_dict_size': 3, 'new_units_added': 1, 'new_units_generated': 2, 'stability': 0.0, 'startup_crash_count': 0, 'timeout_count': 0, 'timeout_limit': 0, } self.stats_getter = stats.StatsGetter(self.fuzzer_stats_invalid_path, self.dict_path) actual_stats = self._set_stats() self.assertEqual(actual_stats, expected_stats)
def test_set_stats_no_file(self): """Tests that set_stats() sets the correct stats or uses default stats when there is no fuzzer_stats file.""" fuzzer_stats_path = self.fuzzer_stats_path + '.nonexistent' self.stats_getter = stats.StatsGetter(fuzzer_stats_path, self.dict_path) expected_stats = { 'actual_duration': 5, 'average_exec_per_sec': 0, 'bad_instrumentation': 0, 'corpus_crash_count': 0, 'corpus_size': 20, 'crash_count': 0, 'dict_used': 1, 'log_lines_unwanted': 0, 'manual_dict_size': 3, 'new_units_added': 1, 'new_units_generated': 2, 'stability': 0.0, 'startup_crash_count': 0, 'timeout_count': 0, 'timeout_limit': 0, } self.assertEqual(self._set_stats(), expected_stats)
def fuzz(self, target_path, options, reproducers_dir, max_time): """Run a fuzz session. Args: target_path: Path to the target. options: The FuzzOptions object returned by prepare(). reproducers_dir: The directory to put reproducers in when crashes are found. max_time: Maximum allowed time for the fuzzing to run. Returns: A FuzzResult object. """ config = launcher.AflConfig.from_target_path(target_path) config.additional_afl_arguments = options.arguments testcase_file_path = os.path.join(reproducers_dir, 'crash') runner = launcher.prepare_runner(target_path, config, testcase_file_path, options.corpus_dir, max_time, strategy_dict=options.strategies) fuzz_result = runner.fuzz() command = fuzz_result.command time_executed = fuzz_result.time_executed fuzzing_logs = fuzz_result.output + runner.fuzzer_stderr # Bail out if AFL returns a nonzero status code. if fuzz_result.return_code: target = engine_common.get_project_qualified_fuzzer_name( target_path) logs.log_error( f'afl: engine encountered an error (target={target})', engine_output=fuzz_result.output) return engine.FuzzResult(fuzzing_logs, command, [], {}, time_executed) stats_getter = stats.StatsGetter(runner.afl_output.stats_path, config.dict_path) new_units_generated, new_units_added, corpus_size = ( runner.libfuzzerize_corpus()) stats_getter.set_stats(fuzz_result.time_executed, new_units_generated, new_units_added, corpus_size, runner.strategies, runner.fuzzer_stderr, fuzz_result.output) crashes = [] if os.path.exists(testcase_file_path): crash = engine.Crash(testcase_file_path, runner.fuzzer_stderr, [], fuzz_result.time_executed) crashes.append(crash) return engine.FuzzResult(fuzzing_logs, command, crashes, stats_getter.stats, time_executed)
def setUp(self): def get_data_path(filename, is_in_output=True): """Returns absolute path of data files used in unittests.""" input_or_output_dir = 'output' if is_in_output else 'input' return os.path.join(self.data_dir, input_or_output_dir, filename) self.data_dir = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'stats_data') self.fuzzer_stats_path = get_data_path('fuzzer_stats') self.fuzzer_stats_invalid_path = get_data_path('fuzzer_stats_invalid') self.dict_path = get_data_path('sample.dict', False) self.stats_getter = stats.StatsGetter(self.fuzzer_stats_path, self.dict_path) self.stats_getter.set_afl_stats() dont_use_strategies(self) self.strategies = launcher.FuzzingStrategies() self.maxDiff = None # pylint: disable=invalid-name