def test_2(self): self.mock.uniform.return_value = 0 self.assertEqual('A2', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 0.4 self.assertEqual('A2', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 1 self.assertEqual('A2', utils.random_weighted_choice(self.list).data)
def test_5(self): self.mock.uniform.return_value = 4.1 self.assertEqual('A5', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 7 self.assertEqual('A5', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 9 self.assertEqual('A5', utils.random_weighted_choice(self.list).data)
def test_3(self): self.mock.uniform.return_value = 1.1 self.assertEqual('A3', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 2 self.assertEqual('A3', utils.random_weighted_choice(self.list).data) self.mock.uniform.return_value = 4 self.assertEqual('A3', utils.random_weighted_choice(self.list).data)
def generate_weighted_strategy_pool(): """Generate a strategy pool based on probability distribution from multi armed bandit experimentation.""" query = data_types.FuzzStrategyProbability.query() distribution = list(ndb_utils.get_all_from_query(query)) # If we are not able to query properly, draw randomly according to # probability parameters. if (not distribution or not environment.get_value('USE_BANDIT_STRATEGY_SELECTION')): return generate_default_strategy_pool() strategy_selection = utils.random_weighted_choice(distribution, 'probability') strategy_name = strategy_selection.strategy_name chosen_strategies = strategy_name.split(',') pool = StrategyPool() for strategy_tuple in strategy.strategy_list: if strategy_tuple.name in chosen_strategies: pool.add_strategy(strategy_tuple) # We consider mutator plugin separately as it is only supported by a small # number of fuzz targets and should be used heavily when available. if do_strategy(strategy.MUTATOR_PLUGIN_STRATEGY): pool.add_strategy(strategy.MUTATOR_PLUGIN_STRATEGY) return pool
def generate_weighted_strategy_pool(strategy_list, use_generator, engine_name): """Generate a strategy pool based on probability distribution from multi armed bandit experimentation.""" # If weighted strategy selection is enabled, there will be a distribution # stored in the environment. distribution = environment.get_value('STRATEGY_SELECTION_DISTRIBUTION') selection_method = environment.get_value('STRATEGY_SELECTION_METHOD', default_value='default') # Otherwise if weighted strategy selection is not enabled (strategy selection # method is default) or if we cannot query properly, generate strategy # pool according to default parameters. We pass the combined list of # multi-armed bandit strategies and manual strategies for consideration in # the default strategy selection process. if not distribution or selection_method == 'default': return generate_default_strategy_pool(strategy_list, use_generator) # Change the distribution to a list of named tuples rather than a list of # dictionaries so that we can use the random_weighted_choice function. Filter # out probability entries from other engines. distribution_tuples = [ StrategyCombination(strategy_name=elem['strategy_name'], probability=elem['probability']) for elem in distribution if elem['engine'] == engine_name ] if not distribution_tuples: logs.log_warn( 'Tried to generate a weighted strategy pool, but do not have ' 'strategy probabilities for %s fuzzing engine.' % engine_name) return generate_default_strategy_pool(strategy_list, use_generator) strategy_selection = utils.random_weighted_choice(distribution_tuples, 'probability') strategy_name = strategy_selection.strategy_name chosen_strategies = strategy_name.split(',') pool = StrategyPool() for strategy_tuple in strategy_list: if strategy_tuple.name in chosen_strategies: pool.add_strategy(strategy_tuple) # We consider certain strategies separately as those are only supported by a # small number of fuzz targets and should be used heavily when available. for value in [ strategy_entry for strategy_entry in strategy_list if strategy_entry.manually_enable ]: if do_strategy(value): pool.add_strategy(value) logs.log('Strategy pool was generated according to weighted distribution. ' 'Chosen strategies: ' + ', '.join(pool.strategy_names)) return pool
def select_fuzz_target(targets, target_weights): """Select a fuzz target from a list of potential targets.""" assert targets weighted_targets = [] for target in targets: weight = target_weights.get(target, 1.0) weighted_targets.append(WeightedTarget(target, weight)) return utils.random_weighted_choice(weighted_targets).target
def generate_weighted_strategy_pool(): """Generate a strategy pool based on probability distribution from multi armed bandit experimentation.""" # If weighted strategy selection is enabled, there will be a distribution # stored in the environment. distribution = environment.get_value('STRATEGY_SELECTION_DISTRIBUTION') selection_method = environment.get_value( 'STRATEGY_SELECTION_METHOD', default_value='default') # Otherwise if weighted strategy selection is not enabled (strategy selection # method is default) or if we cannot query properly, generate strategy # pool according to default parameters. if not distribution or selection_method == 'default': return generate_default_strategy_pool() probability_key = 'probability_medium_temperature' if selection_method == 'multi_armed_bandit_high': probability_key = 'probability_high_temperature' elif selection_method == 'multi_armed_bandit_low': probability_key = 'probability_low_temperature' # Change the distribution to a list of named tuples rather than a list of # dictionaries so that we can use the random_weighted_choice function. distribution_tuples = [ StrategyCombination( strategy_name=elem['strategy_name'], probability=elem[probability_key]) for elem in distribution ] strategy_selection = utils.random_weighted_choice(distribution_tuples, 'probability') strategy_name = strategy_selection.strategy_name chosen_strategies = strategy_name.split(',') pool = StrategyPool() for strategy_tuple in strategy.strategy_list: if strategy_tuple.name in chosen_strategies: pool.add_strategy(strategy_tuple) # We consider certain strategies separately as those are only supported by a # small number of fuzz targets and should be used heavily when available. for value in [ strategy.DATAFLOW_TRACING_STRATEGY, strategy.MUTATOR_PLUGIN_STRATEGY ]: if do_strategy(value): pool.add_strategy(value) logs.log("Strategy pool was generated according to weighted distribution. " "Chosen strategies: " + ", ".join(pool.strategy_names)) return pool
def get_fuzz_task_payload(platform=None): """Select a fuzzer that can run on this platform.""" if not platform: queue_override = environment.get_value('QUEUE_OVERRIDE') platform = queue_override if queue_override else environment.platform() query = data_types.FuzzerJob.query() query = query.filter(data_types.FuzzerJob.platform == platform) mappings = list(ndb_utils.get_all_from_query(query)) if not mappings: return None, None selection = utils.random_weighted_choice(mappings) return selection.fuzzer, selection.job
def generate_weighted_strategy_pool(): """Generate a strategy pool based on probability distribution from multi armed bandit experimentation.""" distribution = environment.get_value('STRATEGY_SELECTION_DISTRIBUTION') # If we are not able to query properly, draw randomly according to # probability parameters. if not distribution: return generate_default_strategy_pool() # Change the distribution to a list of named tuples rather than a list of # dictionaries so that we can use the randome_weighted_choice function. distribution_tuples = [ StrategyCombination( strategy_name=elem['strategy_name'], probability=elem['probability']) for elem in distribution ] strategy_selection = utils.random_weighted_choice(distribution_tuples, 'probability') strategy_name = strategy_selection.strategy_name chosen_strategies = strategy_name.split(',') pool = StrategyPool() for strategy_tuple in strategy.strategy_list: if strategy_tuple.name in chosen_strategies: pool.add_strategy(strategy_tuple) # We consider certain strategies separately as those are only supported by a # small number of fuzz targets and should be used heavily when available. for value in [ strategy.DATAFLOW_TRACING_STRATEGY, strategy.MUTATOR_PLUGIN_STRATEGY ]: if do_strategy(value): pool.add_strategy(value) logs.log("Strategy pool was generated according to weighted distribution. " "Chosen strategies: " + ", ".join(pool.strategy_names)) return pool
def get_fuzz_task_payload(platform=None): """Select a fuzzer that can run on this platform.""" if not platform: queue_override = environment.get_value('QUEUE_OVERRIDE') platform = queue_override if queue_override else environment.platform() if environment.is_local_development(): query = data_types.FuzzerJob.query() query = query.filter(data_types.FuzzerJobs.platform == platform) mappings = list(ndb_utils.get_all_from_query(query)) else: query = data_types.FuzzerJobs.query() query = query.filter(data_types.FuzzerJobs.platform == platform) mappings = [] for entity in query: mappings.extend(entity.fuzzer_jobs) if not mappings: return None, None selection = utils.random_weighted_choice(mappings, weight_attribute='actual_weight') return selection.fuzzer, selection.job
def test_4(self): self.mock.uniform.return_value = 4.1 self.assertNotEqual('A4', utils.random_weighted_choice(self.list).data)