def pick_strategies(strategy_pool, fuzzer_path, corpus_directory, existing_arguments, minijail_chroot=None): """Pick strategies.""" build_directory = environment.get_value('BUILD_DIR') target_name = os.path.basename(fuzzer_path) project_qualified_fuzzer_name = data_types.fuzz_target_project_qualified_name( utils.current_project(), target_name) fuzzing_strategies = [] arguments = [] additional_corpus_dirs = [] # Select a generator to attempt to use for existing testcase mutations. candidate_generator = engine_common.select_generator(strategy_pool, fuzzer_path) is_mutations_run = candidate_generator != engine_common.Generator.NONE # Depends on the presense of DFSan instrumented build. dataflow_build_dir = environment.get_value('DATAFLOW_BUILD_DIR') use_dataflow_tracing = ( dataflow_build_dir and strategy_pool.do_strategy(strategy.DATAFLOW_TRACING_STRATEGY)) if use_dataflow_tracing: dataflow_binary_path = os.path.join( dataflow_build_dir, os.path.relpath(fuzzer_path, build_directory)) if os.path.exists(dataflow_binary_path): arguments.append( '%s%s' % (constants.COLLECT_DATA_FLOW_FLAG, dataflow_binary_path)) fuzzing_strategies.append(strategy.DATAFLOW_TRACING_STRATEGY.name) else: logs.log_error( 'Fuzz target is not found in dataflow build, skiping strategy.') use_dataflow_tracing = False # Generate new testcase mutations using radamsa, etc. if is_mutations_run: new_testcase_mutations_directory = create_corpus_directory('mutations') generator_used = engine_common.generate_new_testcase_mutations( corpus_directory, new_testcase_mutations_directory, project_qualified_fuzzer_name, candidate_generator) # Add the used generator strategy to our fuzzing strategies list. if generator_used: if candidate_generator == engine_common.Generator.RADAMSA: fuzzing_strategies.append( strategy.CORPUS_MUTATION_RADAMSA_STRATEGY.name) elif candidate_generator == engine_common.Generator.ML_RNN: fuzzing_strategies.append(strategy.CORPUS_MUTATION_ML_RNN_STRATEGY.name) additional_corpus_dirs.append(new_testcase_mutations_directory) if minijail_chroot: bind_corpus_dirs(minijail_chroot, [new_testcase_mutations_directory]) if strategy_pool.do_strategy(strategy.RANDOM_MAX_LENGTH_STRATEGY): max_len_argument = fuzzer_utils.extract_argument( existing_arguments, constants.MAX_LEN_FLAG, remove=False) if not max_len_argument: max_length = random.SystemRandom().randint(1, MAX_VALUE_FOR_MAX_LENGTH) arguments.append('%s%d' % (constants.MAX_LEN_FLAG, max_length)) fuzzing_strategies.append(strategy.RANDOM_MAX_LENGTH_STRATEGY.name) if (strategy_pool.do_strategy(strategy.RECOMMENDED_DICTIONARY_STRATEGY) and add_recommended_dictionary(arguments, project_qualified_fuzzer_name, fuzzer_path)): fuzzing_strategies.append(strategy.RECOMMENDED_DICTIONARY_STRATEGY.name) if strategy_pool.do_strategy(strategy.VALUE_PROFILE_STRATEGY): arguments.append(constants.VALUE_PROFILE_ARGUMENT) fuzzing_strategies.append(strategy.VALUE_PROFILE_STRATEGY.name) # DataFlow Tracing requires fork mode, always use it with DFT strategy. if use_dataflow_tracing or strategy_pool.do_strategy(strategy.FORK_STRATEGY): max_fuzz_threads = environment.get_value('MAX_FUZZ_THREADS', 1) num_fuzz_processes = max(1, multiprocessing.cpu_count() // max_fuzz_threads) arguments.append('%s%d' % (constants.FORK_FLAG, num_fuzz_processes)) fuzzing_strategies.append( '%s_%d' % (strategy.FORK_STRATEGY.name, num_fuzz_processes)) extra_env = {} if (strategy_pool.do_strategy(strategy.MUTATOR_PLUGIN_STRATEGY) and use_mutator_plugin(target_name, extra_env, minijail_chroot)): fuzzing_strategies.append(strategy.MUTATOR_PLUGIN_STRATEGY.name) return StrategyInfo(fuzzing_strategies, arguments, additional_corpus_dirs, extra_env, use_dataflow_tracing, is_mutations_run)
def test_lpm_fuzz_target(self): self.assertEqual(engine_common.Generator.NONE, engine_common.select_generator( self.pool, self.FUZZER_PATH)) # pylint: disable=protected-access