def get_corpus_directories(main_corpus_directory, fuzzer_path, fuzzing_strategies, minijail_chroot=None): """Return a list of corpus directories to be passed to the fuzzer binary for fuzzing.""" corpus_directories = [] # Set up scratch directory for writing new units. new_testcases_directory = create_corpus_directory('new') corpus_directories.append(new_testcases_directory) # Check for seed corpus and add it into corpus directory. engine_common.unpack_seed_corpus_if_needed(fuzzer_path, main_corpus_directory) # Pick a few testcases from our corpus to use as the initial corpus. subset_size = engine_common.random_choice( engine_common.CORPUS_SUBSET_NUM_TESTCASES) if (engine_common.do_corpus_subset() and shell.get_directory_file_count(main_corpus_directory) > subset_size): # Copy |subset_size| testcases into 'subset' directory. corpus_subset_directory = create_corpus_directory('subset') copy_from_corpus(corpus_subset_directory, main_corpus_directory, subset_size) corpus_directories.append(corpus_subset_directory) fuzzing_strategies.append(strategy.CORPUS_SUBSET_STRATEGY + '_' + str(subset_size)) if minijail_chroot: bind_corpus_dirs(minijail_chroot, [main_corpus_directory]) else: # Regular fuzzing with the full main corpus directory. corpus_directories.append(main_corpus_directory) if minijail_chroot: bind_corpus_dirs(minijail_chroot, corpus_directories) return corpus_directories
def generate_new_testcase_mutations_using_radamsa( corpus_directory, new_testcase_mutations_directory, expected_completion_time): """Generate new testcase mutations based on Radamsa.""" radamsa_path = get_radamsa_path() if not radamsa_path: # Mutations using radamsa are not supported on current platform, bail out. return radamsa_runner = new_process.ProcessRunner(radamsa_path) files_list = shell.get_files_list(corpus_directory) if not files_list: # No mutations to do on an empty corpus, bail out. return old_corpus_size = shell.get_directory_file_count( new_testcase_mutations_directory) for i in range(RADAMSA_MUTATIONS): original_file_path = engine_common.random_choice(files_list) original_filename = os.path.basename(original_file_path) output_path = os.path.join( new_testcase_mutations_directory, 'radamsa-%08d-%s' % (i + 1, original_filename)) result = radamsa_runner.run_and_wait( ['-o', output_path, original_file_path], timeout=RADAMSA_TIMEOUT) if result.return_code or result.timed_out: logs.log_error('Radamsa failed to mutate or timed out.', output=result.output) # Check if we exceeded our timeout. If yes, do no more mutations and break. if time.time() > expected_completion_time: break new_corpus_size = shell.get_directory_file_count( new_testcase_mutations_directory) logs.log('Added %d tests using Radamsa mutations.' % (new_corpus_size - old_corpus_size))
def prepare(self, corpus_dir, target_path, _): """Prepare for a fuzzing session, by generating options. Returns a FuzzOptions object. Args: corpus_dir: The main corpus directory. target_path: Path to the target. build_dir: Path to the build directory. Returns: A FuzzOptions object. """ arguments = fuzzer.get_arguments(target_path) strategy_pool = strategy_selection.generate_weighted_strategy_pool( strategy_list=strategy.LIBFUZZER_STRATEGY_LIST, use_generator=True, engine_name=self.name) strategy_info = launcher.pick_strategies(strategy_pool, target_path, corpus_dir, arguments) arguments.extend(strategy_info.arguments) # Check for seed corpus and add it into corpus directory. engine_common.unpack_seed_corpus_if_needed(target_path, corpus_dir) # Pick a few testcases from our corpus to use as the initial corpus. subset_size = engine_common.random_choice( engine_common.CORPUS_SUBSET_NUM_TESTCASES) if (not strategy_info.use_dataflow_tracing and strategy_pool.do_strategy(strategy.CORPUS_SUBSET_STRATEGY) and shell.get_directory_file_count(corpus_dir) > subset_size): # Copy |subset_size| testcases into 'subset' directory. corpus_subset_dir = self._create_temp_corpus_dir('subset') launcher.copy_from_corpus(corpus_subset_dir, corpus_dir, subset_size) strategy_info.fuzzing_strategies.append( strategy.CORPUS_SUBSET_STRATEGY.name + '_' + str(subset_size)) strategy_info.additional_corpus_dirs.append(corpus_subset_dir) else: strategy_info.additional_corpus_dirs.append(corpus_dir) # Check dict argument to make sure that it's valid. dict_argument = fuzzer_utils.extract_argument(arguments, constants.DICT_FLAG, remove=False) if dict_argument and not os.path.exists(dict_argument): logs.log_error('Invalid dict %s for %s.' % (dict_argument, target_path)) fuzzer_utils.extract_argument(arguments, constants.DICT_FLAG) # If there's no dict argument, check for %target_binary_name%.dict file. if (not fuzzer_utils.extract_argument( arguments, constants.DICT_FLAG, remove=False)): default_dict_path = dictionary_manager.get_default_dictionary_path( target_path) if os.path.exists(default_dict_path): arguments.append(constants.DICT_FLAG + default_dict_path) return LibFuzzerOptions(corpus_dir, arguments, strategy_info.fuzzing_strategies, strategy_info.additional_corpus_dirs, strategy_info.extra_env, strategy_info.use_dataflow_tracing, strategy_info.is_mutations_run)