3636from clusterfuzz ._internal .bot .tasks import setup
3737from clusterfuzz ._internal .bot .tasks import task_creation
3838from clusterfuzz ._internal .bot .tasks import trials
39+ from clusterfuzz ._internal .bot .tasks .utasks import fuzz_task_knobs
3940from clusterfuzz ._internal .bot .tasks .utasks import uworker_handle_errors
4041from clusterfuzz ._internal .bot .tasks .utasks import uworker_io
4142from clusterfuzz ._internal .build_management import build_manager
4445from clusterfuzz ._internal .crash_analysis .stack_parsing import stack_analyzer
4546from clusterfuzz ._internal .datastore import data_handler
4647from clusterfuzz ._internal .datastore import data_types
47- from clusterfuzz ._internal .datastore import ndb_utils
4848from clusterfuzz ._internal .fuzzing import corpus_manager
4949from clusterfuzz ._internal .fuzzing import fuzzer_selection
50- from clusterfuzz ._internal .fuzzing import gesture_handler
5150from clusterfuzz ._internal .fuzzing import leak_blacklist
5251from clusterfuzz ._internal .google_cloud_utils import big_query
5352from clusterfuzz ._internal .google_cloud_utils import blobs
6463from clusterfuzz .fuzz import engine
6564from clusterfuzz .stacktraces .__init__ import CrashInfo
6665
67- SelectionMethod = collections .namedtuple ('SelectionMethod' ,
68- 'method_name probability' )
69-
70- DEFAULT_CHOOSE_PROBABILITY = 9 # 10%
7166FUZZER_METADATA_REGEX = re .compile (r'metadata::(\w+):\s*(.*)' )
7267FUZZER_FAILURE_THRESHOLD = 0.33
73- MAX_GESTURES = 30
7468MAX_NEW_CORPUS_FILES = 500
75- SELECTION_METHOD_DISTRIBUTION = [
76- SelectionMethod ('default' , .7 ),
77- SelectionMethod ('multi_armed_bandit' , .3 )
78- ]
7969THREAD_WAIT_TIMEOUT = 1
8070
8171
@@ -102,33 +92,12 @@ class FuzzErrorCode:
10292 'timeout_multiplier' , 'test_timeout' , 'thread_wait_timeout' ,
10393 'data_directory'
10494])
105- Redzone = collections .namedtuple ('Redzone' , ['size' , 'weight' ])
10695
10796GenerateBlackboxTestcasesResult = collections .namedtuple (
10897 'GenerateBlackboxTestcasesResult' ,
10998 ['success' , 'testcase_file_paths' , 'fuzzer_metadata' ])
11099
111100
112- def do_multiarmed_bandit_strategy_selection (uworker_env ):
113- """Set multi-armed bandit strategy selection during preprocessing. Set
114- multi-armed bandit strategy selection distribution as an environment variable
115- so we can access it in launcher."""
116- # TODO: Remove environment variable once fuzzing engine refactor is
117- # complete.
118- if not environment .get_value (
119- 'USE_BANDIT_STRATEGY_SELECTION' , env = uworker_env ):
120- return
121- selection_method = utils .random_weighted_choice (SELECTION_METHOD_DISTRIBUTION ,
122- 'probability' )
123- environment .set_value ('STRATEGY_SELECTION_METHOD' ,
124- selection_method .method_name , uworker_env )
125- distribution = get_strategy_distribution_from_ndb ()
126- if not distribution :
127- return
128- environment .set_value ('STRATEGY_SELECTION_DISTRIBUTION' , distribution ,
129- uworker_env )
130-
131-
132101def has_standard_build ():
133102 if environment .platform () == 'FUCHSIA' :
134103 return False
@@ -663,135 +632,13 @@ def get_testcases(testcase_count, testcase_directory, data_directory):
663632 generated_testcase_string )
664633
665634
666- def pick_gestures (test_timeout ):
667- """Return a list of random gestures."""
668- if not environment .get_value ('ENABLE_GESTURES' , True ):
669- # Gestures disabled.
670- return []
671-
672- # Probability of choosing gestures.
673- if utils .random_number (0 , DEFAULT_CHOOSE_PROBABILITY ):
674- return []
675-
676- gesture_count = utils .random_number (1 , MAX_GESTURES )
677- gestures = gesture_handler .get_gestures (gesture_count )
678- if not gestures :
679- return []
680-
681- # Pick a random trigger time to run the gesture at.
682- min_gesture_time = int (
683- utils .random_element_from_list ([0.25 , 0.50 , 0.50 , 0.50 ]) * test_timeout )
684- max_gesture_time = test_timeout - 1
685- gesture_time = utils .random_number (min_gesture_time , max_gesture_time )
686-
687- gestures .append ('Trigger:%d' % gesture_time )
688- return gestures
689-
690-
691- def pick_redzone ():
692- """Return a random size for redzone."""
693- thread_multiplier = environment .get_value ('THREAD_MULTIPLIER' , 1 )
694-
695- if thread_multiplier == 1 :
696- redzone_list = [
697- Redzone (16 , 1.0 ),
698- Redzone (32 , 1.0 ),
699- Redzone (64 , 0.5 ),
700- Redzone (128 , 0.5 ),
701- Redzone (256 , 0.25 ),
702- Redzone (512 , 0.25 ),
703- ]
704- else :
705- # For beefier boxes, prioritize using bigger redzones.
706- redzone_list = [
707- Redzone (16 , 0.25 ),
708- Redzone (32 , 0.25 ),
709- Redzone (64 , 0.50 ),
710- Redzone (128 , 0.50 ),
711- Redzone (256 , 1.0 ),
712- Redzone (512 , 1.0 ),
713- ]
714-
715- return utils .random_weighted_choice (redzone_list ).size
716-
717-
718- def pick_ubsan_disabled (job_type ):
719- """Choose whether to disable UBSan in an ASan+UBSan build."""
720- # This is only applicable in an ASan build.
721- memory_tool_name = environment .get_memory_tool_name (job_type )
722- if memory_tool_name not in ['ASAN' , 'HWASAN' ]:
723- return False
724-
725- # Check if UBSan is enabled in this ASan build. If not, can't disable it.
726- if not environment .get_value ('UBSAN' ):
727- return False
728-
729- return not utils .random_number (0 , DEFAULT_CHOOSE_PROBABILITY )
730-
731-
732- def pick_timeout_multiplier ():
733- """Return a random testcase timeout multiplier and adjust timeout."""
734- fuzz_test_timeout = environment .get_value ('FUZZ_TEST_TIMEOUT' )
735- custom_timeout_multipliers = environment .get_value (
736- 'CUSTOM_TIMEOUT_MULTIPLIERS' )
737- timeout_multiplier = 1.0
738-
739- use_multiplier = not utils .random_number (0 , DEFAULT_CHOOSE_PROBABILITY )
740- if (use_multiplier and not fuzz_test_timeout and
741- not custom_timeout_multipliers ):
742- timeout_multiplier = utils .random_element_from_list ([0.5 , 1.5 , 2.0 , 3.0 ])
743- elif use_multiplier and custom_timeout_multipliers :
744- # Since they are explicitly set in the job definition, it is fine to use
745- # custom timeout multipliers even in the case where FUZZ_TEST_TIMEOUT is
746- # set.
747- timeout_multiplier = utils .random_element_from_list (
748- custom_timeout_multipliers )
749-
750- return timeout_multiplier
751-
752-
753635def set_test_timeout (timeout , multipler ):
754636 """Set the test timeout based on a timeout value and multiplier."""
755637 test_timeout = int (timeout * multipler )
756638 environment .set_value ('TEST_TIMEOUT' , test_timeout )
757639 return test_timeout
758640
759641
760- def pick_window_argument ():
761- """Return a window argument with random size and x,y position."""
762- default_window_argument = environment .get_value ('WINDOW_ARG' , '' )
763- window_argument_change_chance = not utils .random_number (
764- 0 , DEFAULT_CHOOSE_PROBABILITY )
765-
766- window_argument = ''
767- if window_argument_change_chance :
768- window_argument = default_window_argument
769- if window_argument :
770- width = utils .random_number (
771- 100 , utils .random_element_from_list ([256 , 1280 , 2048 ]))
772- height = utils .random_number (
773- 100 , utils .random_element_from_list ([256 , 1024 , 1536 ]))
774- left = utils .random_number (0 , width )
775- top = utils .random_number (0 , height )
776-
777- window_argument = window_argument .replace ('$WIDTH' , str (width ))
778- window_argument = window_argument .replace ('$HEIGHT' , str (height ))
779- window_argument = window_argument .replace ('$LEFT' , str (left ))
780- window_argument = window_argument .replace ('$TOP' , str (top ))
781-
782- # FIXME: Random seed is currently passed along to the next job
783- # via WINDOW_ARG. Rename it without breaking existing tests.
784- random_seed_argument = environment .get_value ('RANDOM_SEED' )
785- if random_seed_argument :
786- if window_argument :
787- window_argument += ' '
788- seed = utils .random_number (- 2147483648 , 2147483647 )
789- window_argument += '%s=%d' % (random_seed_argument .strip (), seed )
790-
791- environment .set_value ('WINDOW_ARG' , window_argument )
792- return window_argument
793-
794-
795642def truncate_fuzzer_output (output , limit ):
796643 """Truncate output in the middle according to limit."""
797644 if len (output ) < limit :
@@ -1228,19 +1075,6 @@ def key_fn(crash):
12281075 return new_crash_count , known_crash_count , processed_groups
12291076
12301077
1231- def get_strategy_distribution_from_ndb ():
1232- """Queries and returns the distribution stored in the ndb table."""
1233- query = data_types .FuzzStrategyProbability .query ()
1234- distribution = []
1235- for strategy_entry in list (ndb_utils .get_all_from_query (query )):
1236- distribution .append ({
1237- 'strategy_name' : strategy_entry .strategy_name ,
1238- 'probability' : strategy_entry .probability ,
1239- 'engine' : strategy_entry .engine
1240- })
1241- return distribution
1242-
1243-
12441078def _get_issue_metadata_from_environment (variable_name ):
12451079 """Get issue metadata from environment."""
12461080 values = str (environment .get_value_string (variable_name , '' )).split (',' )
@@ -1330,10 +1164,10 @@ def __init__(self, uworker_input, test_timeout):
13301164 self .uworker_input = uworker_input
13311165
13321166 # Set up randomly selected fuzzing parameters.
1333- self .redzone = pick_redzone ()
1334- self .disable_ubsan = pick_ubsan_disabled (self .job_type )
1335- self .timeout_multiplier = pick_timeout_multiplier ()
1336- self .window_argument = pick_window_argument ()
1167+ self .redzone = fuzz_task_knobs . pick_redzone ()
1168+ self .disable_ubsan = fuzz_task_knobs . pick_ubsan_disabled (self .job_type )
1169+ self .timeout_multiplier = fuzz_task_knobs . pick_timeout_multiplier ()
1170+ self .window_argument = fuzz_task_knobs . pick_window_argument ()
13371171 self .test_timeout = set_test_timeout (test_timeout , self .timeout_multiplier )
13381172
13391173 # Set up during run().
@@ -1666,8 +1500,8 @@ def do_blackbox_fuzzing(self, fuzzer, fuzzer_directory, job_type):
16661500 testcases_metadata [testcase_file_path ] = {}
16671501
16681502 # Pick up a gesture to run on the testcase.
1669- testcases_metadata [testcase_file_path ]['gestures' ] = pick_gestures (
1670- test_timeout )
1503+ testcases_metadata [testcase_file_path ]['gestures' ] = (
1504+ fuzz_task_knobs . pick_gestures ( test_timeout ) )
16711505
16721506 # Prepare selecting trials in main loop below.
16731507 trial_selector = trials .Trials ()
@@ -2071,7 +1905,7 @@ def _preprocess_get_fuzz_target(fuzzer_name, job_type):
20711905def utask_preprocess (fuzzer_name , job_type , uworker_env ):
20721906 """Preprocess untrusted task."""
20731907 setup_input = setup .preprocess_update_fuzzer_and_data_bundles (fuzzer_name )
2074- do_multiarmed_bandit_strategy_selection (uworker_env )
1908+ fuzz_task_knobs . do_multiarmed_bandit_strategy_selection (uworker_env )
20751909 environment .set_value ('PROJECT_NAME' , data_handler .get_project_name (job_type ),
20761910 uworker_env )
20771911 fuzz_target = _preprocess_get_fuzz_target (fuzzer_name , job_type )
0 commit comments