def setUp(self): helpers.patch(self, [ 'build_management.build_manager.get_primary_bucket_path', 'build_management.build_manager.get_revisions_list', 'build_management.revisions.get_component_range_list', 'config.local_config.ProjectConfig', 'google_cloud_utils.blobs.read_key', 'google_cloud_utils.pubsub.PubSubClient.publish', ]) data_types.FuzzTarget(id='libFuzzer_proj_target', engine='libFuzzer', project='proj', binary='target').put() self.testcase = data_types.Testcase( timestamp=datetime.datetime(2021, 1, 1), crash_type='crash-type', crash_state='A\nB\nC', security_flag=True, bug_information='1337', job_type='libfuzzer_asan_proj', fuzzer_name='libFuzzer', overridden_fuzzer_name='libFuzzer_proj_target', regression='123:456', fixed='123:456', crash_revision=3, security_severity=data_types.SecuritySeverity.MEDIUM, additional_metadata='{"last_tested_crash_revision": 4}') self.testcase.put() self.mock.read_key.return_value = b'reproducer' self.mock.get_component_range_list.return_value = [ { 'link_text': 'old:new', }, ] self.mock.ProjectConfig.return_value = mock_config.MockConfig({ 'bisect_service': { 'pubsub_topic': '/projects/project/topics/topic', } })
def setUp(self): test_helpers.patch(self, [ 'libs.access._is_domain_allowed', 'libs.access.has_access', 'libs.helpers.get_user_email', 'config.db_config.get', 'issue_management.issue_tracker_utils.get_issue_tracker_manager', 'issue_management.issue_tracker_manager.IssueTrackerManager', ]) itm = issue_tracker_manager.IssueTrackerManager('test') self.mock.get_issue_tracker_manager.return_value = itm self.get_issue = itm.get_issue self.email = '*****@*****.**' self.mock.get_user_email.return_value = self.email self.bug = issue.Issue() self.testcase = data_types.Testcase() self.mock.get.return_value = (data_types.Config( relax_testcase_restrictions=True))
def test_minimize(self): """Test minimize.""" testcase_file_path = os.path.join(self.temp_dir, 'testcase') with open(testcase_file_path, 'wb') as f: f.write('EEE') with open(testcase_file_path) as f: fuzzed_keys = blobs.write_blob(f) testcase_path = os.path.join(self.temp_dir, 'testcase') testcase = data_types.Testcase( crash_type='Null-dereference WRITE', crash_address='', crash_state='Foo\n', crash_stacktrace='', crash_revision=1337, fuzzed_keys=fuzzed_keys, fuzzer_name='libFuzzer', overridden_fuzzer_name='libFuzzer_test_fuzzer', job_type='libfuzzer_asan_job', original_absolute_path=testcase_path, absolute_path=testcase_path, minimized_arguments='%TESTCASE% test_fuzzer') testcase.put() self._setup_env(job_type='libfuzzer_asan_job') environment.set_value('APP_ARGS', testcase.minimized_arguments) environment.set_value('LIBFUZZER_MINIMIZATION_ROUNDS', 3) minimize_task.execute_task(testcase.key.id(), 'libfuzzer_asan_job') testcase = data_handler.get_testcase_by_id(testcase.key.id()) self.assertNotEqual('', testcase.minimized_keys) self.assertNotEqual('NA', testcase.minimized_keys) self.assertNotEqual(testcase.fuzzed_keys, testcase.minimized_keys) self.assertEqual({'ASAN_OPTIONS': {}}, testcase.get_metadata('env')) blobs.read_blob_to_disk(testcase.minimized_keys, testcase_path) with open(testcase_path) as f: self.assertEqual(1, len(f.read()))
def test_libfuzzer_skip_minimization_initial_crash_state(self): """Test libFuzzer minimization skipping with a valid initial crash state.""" # TODO(ochang): Fix circular import. from crash_analysis.crash_result import CrashResult testcase = data_types.Testcase( minimized_keys="", fuzzed_keys="FUZZED_KEY", job_type="libfuzzer_asan_job", security_flag=True, ) testcase.put() stacktrace = ( "==14970==ERROR: AddressSanitizer: heap-buffer-overflow on address " "0x61b00001f7d0 at pc 0x00000064801b bp 0x7ffce478dbd0 sp " "0x7ffce478dbc8 READ of size 4 at 0x61b00001f7d0 thread T0\n" "#0 0x64801a in frame0() src/test.cpp:1819:15\n" "#1 0x647ac5 in frame1() src/test.cpp:1954:25\n" "#2 0xb1dee7 in frame2() src/test.cpp:160:9\n" "#3 0xb1ddd8 in frame3() src/test.cpp:148:34\n") self.mock._run_libfuzzer_testcase.return_value = CrashResult( # pylint: disable=protected-access 1, 1.0, stacktrace) self.mock._run_libfuzzer_tool.return_value = ( None, None, ) # pylint: disable=protected-access minimize_task.do_libfuzzer_minimization(testcase, "/testcase_file_path") testcase = data_handler.get_testcase_by_id(testcase.key.id()) self.assertEqual("Heap-buffer-overflow", testcase.crash_type) self.assertEqual("frame0\nframe1\nframe2\n", testcase.crash_state) self.assertEqual("0x61b00001f7d0", testcase.crash_address) self.assertEqual( "+----------------------------------------Release Build Stacktrace" "----------------------------------------+\n%s" % stacktrace, testcase.crash_stacktrace, )
def test_engine_fuzzer_job(self): """Test variant task with an engine fuzzer job.""" testcase = data_types.Testcase( job_type='libfuzzer_asan_project', fuzzer_name='libFuzzer', overridden_fuzzer_name='libfuzzer_project_binary_name', project_name='project', crash_type='crash-type', crash_address='0x1337', crash_state='A\nB\nC\n', crash_revision=1337) testcase.set_metadata('fuzzer_binary_name', 'binary_name', update_testcase=True) job = data_types.Job() job.name = 'afl_asan_project' job.environment_string = 'PROJECT_NAME = project\n' job.put() variant_testcase = variant_task._get_variant_testcase_for_job( # pylint: disable=protected-access testcase, 'afl_asan_project') self.assertNotEqual(testcase, variant_testcase) self.assertEqual(testcase.key.id(), variant_testcase.key.id()) self.assertEqual('afl', variant_testcase.fuzzer_name) self.assertEqual('afl_project_binary_name', variant_testcase.overridden_fuzzer_name) self.assertEqual('afl_asan_project', variant_testcase.job_type) self.assertEqual('crash-type', variant_testcase.crash_type) self.assertEqual('0x1337', variant_testcase.crash_address) self.assertEqual('A\nB\nC\n', variant_testcase.crash_state) self.assertEqual(1337, variant_testcase.crash_revision) self.assertEqual('binary_name', variant_testcase.get_metadata('fuzzer_binary_name')) # Test that a put() call does not change original testcase. variant_testcase.comments = 'ABC' variant_testcase.put() testcase = data_handler.get_testcase_by_id(testcase.key.id()) self.assertEqual('', testcase.comments)
def setUp(self): flaskapp = flask.Flask('testflask') flaskapp.add_url_rule('/external-update', view_func=external_update.Handler.as_view('')) self.app = webtest.TestApp(flaskapp) test_helpers.patch(self, [ 'base.utils.utcnow', 'google.oauth2.id_token.verify_oauth2_token', ]) self.mock.verify_oauth2_token.return_value = { 'email_verified': True, 'email': '*****@*****.**', } self.mock.utcnow.return_value = datetime.datetime(2021, 1, 1) data_types.Job(name='libfuzzer_external_job', external_reproduction_topic='topic', external_updates_subscription='subscription').put() data_types.Job(name='job').put() data_types.FuzzTarget(engine='libFuzzer', binary='fuzzer').put() self.testcase = data_types.Testcase( open=True, status='Processed', fuzzer_name='libFuzzer', overridden_fuzzer_name='libFuzzer_fuzzer', job_type='libfuzzer_external_job', crash_state=('blink::InputTypeView::element\n' 'blink::TextFieldInputType::didSetValueByUserEdit\n' 'blink::TextFieldInputType::subtreeHasChanged\n'), crash_revision=1336, crash_stacktrace='original', last_tested_crash_stacktrace='last_tested', crash_type='', security_flag=True) self.testcase.put()
def test_blackbox_fuzzer_testcase_with_default_help_format(self): """Test the function with a blackbox fuzzer test case, with HELP_FORMAT set in environment.""" environment.set_value( 'HELP_FORMAT', '-%TESTCASE%\\n-%FUZZER_NAME%\\n-%FUZZ_TARGET%\\n-%PROJECT%\\n' '-%REVISION%\\n-%ENGINE%\\n-%SANITIZER%\\n%ARGS%\\n' '%SANITIZER_OPTIONS%./binary') testcase = data_types.Testcase() testcase.fuzzer_name = 'simple_fuzzer' testcase.job_type = 'ubsan_job_without_help_format' testcase.crash_revision = 1337 testcase.put() testcase.set_metadata( 'env', { 'ASAN_OPTIONS': { 'handle_abort': 1, 'symbolize': 0, 'redzone': 512, }, 'UBSAN_OPTIONS': { 'halt_on_error': 1, 'symbolize': 0, }, 'OTHER_OPTIONS': { 'symbolize': 1 } }) self.assertEquals( data_handler.get_formatted_reproduction_help(testcase), ('-{id}\n-simple_fuzzer\n-NA\n-test_project\n-1337\n' '-NA\n-UBSAN\n--disable-logging --disable-experiments\n' 'ASAN_OPTIONS="handle_abort=1:redzone=512" ' 'UBSAN_OPTIONS="halt_on_error=1" ./binary').format( id=testcase.key.id()))
def setUp(self): test_helpers.patch(self, [ 'issue_management.label_utils.get_memory_tool_labels', 'libs.issue_filer.add_view_restrictions_if_needed', 'datastore.data_handler.get_issue_description', 'datastore.data_handler.get_issue_summary', 'datastore.data_handler.get_stacktrace', 'datastore.data_handler.update_group_bug', 'libs.helpers.get_issue_tracker_for_testcase', 'libs.auth.get_current_user', 'handlers.testcase_detail.show.get_testcase_detail', 'libs.access.get_access', ]) self.mock.get_access.return_value = access.UserAccess.Allowed self.mock.get_testcase_detail.return_value = {'testcase': 'yes'} self.mock.get_current_user().email = '*****@*****.**' self.app = webtest.TestApp( webapp2.WSGIApplication([('/', update_issue.Handler)])) self.testcase = data_types.Testcase() self.testcase.bug_information = 'unset' self.testcase.put()
def test_duplicate(self): """Test duplicate.""" expected_crash_state = 'Foo\nBar\nMain\n' data_types.Testcase(open=True, status='Processed', crash_state=expected_crash_state, crash_type='Heap-buffer-overflow\nWRITE 4', project_name='project', security_flag=True).put() response = self.app.post_json( '/', { 'project': 'project', 'fuzz_target': 'target', 'stacktrace': TEST_STACKTRACE_OVERFLOW, }) self.assertEqual( { 'result': 'duplicate', 'type': 'Heap-buffer-overflow\nWRITE 4', 'state': expected_crash_state, 'security': True, }, response.json)
def setUp(self): self.minimized_key = 'minimized' self.fuzzed_key = 'fuzzed' self.unused_key = 'unused' self.testcase = data_types.Testcase(minimized_keys=self.minimized_key, fuzzed_keys=self.fuzzed_key, bug_information='1337') self.testcase.put() test_helpers.patch(self, [ 'base.utils.is_oss_fuzz', 'google_cloud_utils.blobs.get_blob_info', 'libs.access.can_user_access_testcase', 'libs.access.has_access', 'libs.gcs.get_signed_url', 'libs.helpers.get_user_email', 'libs.issue_management.issue_tracker_utils.' 'get_issue_tracker_for_testcase', ]) self.mock.is_oss_fuzz.return_value = False self.mock.can_user_access_testcase.return_value = False self.mock.has_access.return_value = False self.mock.get_user_email.return_value = '*****@*****.**' self.mock.get_signed_url.side_effect = ( lambda b, p: 'https://SIGNED_URL?path=' + p) self.mock.get_blob_info.side_effect = (lambda key: storage.GcsBlobInfo( 'blobs-bucket', key, 'file.ext', 1337)) flaskapp = flask.Flask('testflask') flaskapp.add_url_rule('/download', view_func=download.Handler.as_view('')) flaskapp.add_url_rule( '/download/<resource>', view_func=download.Handler.as_view('/download/<resource>')) self.app = webtest.TestApp(flaskapp)
def setUp(self): helpers.patch(self, [ 'build_management.revisions.get_component_range_list', 'config.local_config.ProjectConfig', 'google_cloud_utils.blobs.read_key', 'google_cloud_utils.pubsub.PubSubClient.publish', ]) data_types.FuzzTarget( id='libFuzzer_proj_target', engine='libFuzzer', project='proj', binary='target').put() self.testcase = data_types.Testcase( crash_type='crash-type', security_flag=True, bug_information='1337', job_type='libfuzzer_asan_proj', fuzzer_name='libFuzzer', overridden_fuzzer_name='libFuzzer_proj_target', regression='123:456', fixed='123:456') self.testcase.put() self.mock.read_key.return_value = b'reproducer' self.mock.get_component_range_list.return_value = [ { 'link_text': 'old:new', }, ] self.mock.ProjectConfig.return_value = mock_config.MockConfig({ 'bisect_service': { 'pubsub_topic': '/projects/project/topics/topic', } })
def test_libfuzzer_skip_minimization_initial_crash_state(self): """Test libFuzzer minimization skipping with a valid initial crash state.""" # TODO(ochang): Fix circular import. from crash_analysis.crash_result import CrashResult testcase = data_types.Testcase(minimized_keys='', fuzzed_keys='FUZZED_KEY', job_type='libfuzzer_asan_job', security_flag=True) testcase.put() stacktrace = ( '==14970==ERROR: AddressSanitizer: heap-buffer-overflow on address ' '0x61b00001f7d0 at pc 0x00000064801b bp 0x7ffce478dbd0 sp ' '0x7ffce478dbc8 READ of size 4 at 0x61b00001f7d0 thread T0\n' '#0 0x64801a in frame0() src/test.cpp:1819:15\n' '#1 0x647ac5 in frame1() src/test.cpp:1954:25\n' '#2 0xb1dee7 in frame2() src/test.cpp:160:9\n' '#3 0xb1ddd8 in frame3() src/test.cpp:148:34\n') self.mock._run_libfuzzer_testcase.return_value = CrashResult( # pylint: disable=protected-access 1, 1.0, stacktrace) self.mock._run_libfuzzer_tool.return_value = (None, None) # pylint: disable=protected-access minimize_task.do_libfuzzer_minimization(testcase, '/testcase_file_path') testcase = data_handler.get_testcase_by_id(testcase.key.id()) self.assertEqual('Heap-buffer-overflow', testcase.crash_type) self.assertEqual('frame0\nframe1\nframe2\n', testcase.crash_state) self.assertEqual('0x61b00001f7d0', testcase.crash_address) self.assertEqual( '[Command line] python /libfuzzer/launcher.py /testcase_file_path ' 'fuzz_target\n\n' '+----------------------------------------Release Build Stacktrace' '----------------------------------------+\n%s' % stacktrace, testcase.crash_stacktrace)
def test_set(self): """Test set everything.""" os.environ['FAIL_RETRIES'] = '3' os.environ['FAIL_WAIT'] = '3' os.environ['BUILD_KEY'] = 'build_key_value' os.environ['BUILD_KEY'] = 'build_key_value' os.environ['BUILD_URL'] = 'build_url_value' os.environ['APP_DIR'] = 'app_dir_value' os.environ['GN_ARGS_PATH'] = 'app_dir_value/args.gn' self.fs.CreateFile('app_dir_value/args.gn', contents=('is_asan = true\n' 'goma_dir = /home/user/goma\n' 'use_goma = true\n' 'v8_enable_verify_heap = true')) testcase = data_types.Testcase() data_handler.set_initial_testcase_metadata(testcase) metadata = json.loads(testcase.additional_metadata) self.assertEqual('build_key_value', metadata['build_key']) self.assertEqual('build_url_value', metadata['build_url']) self.assertEqual( 'is_asan = true\nuse_goma = true\nv8_enable_verify_heap = true', metadata['gn_args'])
def setUp(self): helpers.patch(self, [ 'config.local_config.ProjectConfig', ]) self.topic = 'projects/project/topics/issue-updates' self.subscription = 'projects/project/subscriptions/issue-updates' self.mock.ProjectConfig.return_value = mock_config.MockConfig({ 'issue_updates': { 'pubsub_topic': self.topic, }, }) self.pubsub_client = pubsub.PubSubClient() self.pubsub_client.create_topic(self.topic) self.pubsub_client.create_subscription(self.subscription, self.topic) self.testcase = data_types.Testcase(crash_address='0xffff', security_flag=True, crash_type='CRASH TYPE', crash_state='CRASH STATE', bug_information='123') self.testcase.put()
def setUp(self): self.minimized_key = 'minimized' self.fuzzed_key = 'fuzzed' self.unused_key = 'unused' self.testcase = data_types.Testcase( minimized_keys=self.minimized_key, fuzzed_keys=self.fuzzed_key, bug_information='1337') self.testcase.put() test_helpers.patch(self, [ 'base.utils.is_oss_fuzz', 'google_cloud_utils.blobs.get_blob_info', 'libs.access.can_user_access_testcase', 'libs.access.has_access', 'libs.gcs.get_signed_url', 'libs.helpers.get_user_email', 'libs.issue_management.issue_tracker_utils.' 'get_issue_tracker_for_testcase', ]) self.mock.is_oss_fuzz.return_value = False self.mock.can_user_access_testcase.return_value = False self.mock.has_access.return_value = False self.mock.get_user_email.return_value = '*****@*****.**' self.mock.get_signed_url.side_effect = ( lambda b, p: 'https://SIGNED_URL?path=' + p) self.mock.get_blob_info.side_effect = ( lambda key: storage.GcsBlobInfo('blobs-bucket', key, 'file.ext', 1337)) self.app = webtest.TestApp( webapp2.WSGIApplication( [ ('/download/?([^/]+)?', download.Handler), ], debug=True))
def test_bazel_test_args(self): """Test bazel test args with a libFuzzer test case""" environment.set_value('HELP_FORMAT', 'bazel test %BAZEL_TEST_ARGS%') testcase = data_types.Testcase() testcase.fuzzer_name = 'libFuzzer' testcase.overridden_fuzzer_name = 'libFuzzer_test_project_test_fuzzer' testcase.job_type = 'ubsan_job_without_help_format' testcase.crash_revision = 1337 testcase.minimized_arguments = ( '%TESTCASE% test_fuzzer -arg1=val1 -arg2="val2 val3"') testcase.put() testcase.set_metadata( 'env', { 'ASAN_OPTIONS': { 'handle_abort': 1, 'symbolize': 0, 'redzone': 512, }, 'UBSAN_OPTIONS': { 'halt_on_error': 1, 'symbolize': 0, }, 'OTHER_OPTIONS': { 'symbolize': 1 } }) self.assertEqual( data_handler.get_formatted_reproduction_help(testcase), 'bazel test ' '--test_env=ASAN_OPTIONS="handle_abort=1:redzone=512" ' '--test_env=UBSAN_OPTIONS="halt_on_error=1" ' '--test_arg=-arg1=val1 ' '--test_arg=\'-arg2=val2 val3\'')
def create_user_uploaded_testcase(key, original_key, archive_state, filename, file_path_input, timeout, job_type, queue, http_flag, gestures, additional_arguments, bug_information, crash_revision, uploader_email, platform_id, app_launch_command, fuzzer_name, fully_qualified_fuzzer_name, fuzzer_binary_name, bundled, retries, bug_summary_update_flag, additional_metadata=None): """Create a testcase object, metadata, and task for a user uploaded test.""" testcase = data_types.Testcase() testcase.crash_type = '' testcase.crash_state = 'Pending' testcase.crash_address = '' testcase.crash_stacktrace = '' testcase.fuzzed_keys = key testcase.minimized_keys = '' testcase.bug_information = '' testcase.regression = '' testcase.fixed = '' testcase.security_flag = False testcase.one_time_crasher_flag = False testcase.crash_revision = crash_revision testcase.comments = '[%s] %s: Analyze task.\n' % (utils.current_date_time(), uploader_email) testcase.fuzzer_name = fuzzer_name testcase.overridden_fuzzer_name = fully_qualified_fuzzer_name or fuzzer_name testcase.job_type = job_type testcase.http_flag = bool(http_flag) testcase.archive_state = archive_state testcase.status = 'Pending' testcase.project_name = get_project_name(job_type) if archive_state or bundled: testcase.absolute_path = file_path_input testcase.archive_filename = filename else: testcase.absolute_path = filename testcase.gestures = gestures if bug_information: testcase.bug_information = bug_information if platform_id: testcase.platform_id = platform_id.strip().lower() if additional_arguments: testcase.set_metadata( 'uploaded_additional_args', additional_arguments, update_testcase=False) if app_launch_command: testcase.set_metadata( 'app_launch_command', app_launch_command, update_testcase=False) if fuzzer_binary_name: testcase.set_metadata( 'fuzzer_binary_name', fuzzer_binary_name, update_testcase=False) if additional_metadata: for metadata_key, metadata_value in six.iteritems(additional_metadata): testcase.set_metadata(metadata_key, metadata_value, update_testcase=False) testcase.timestamp = datetime.datetime.utcnow() testcase.uploader_email = uploader_email testcase.put() # Store the testcase upload metadata. testcase_id = testcase.key.id() metadata = data_types.TestcaseUploadMetadata() metadata.security_flag = False metadata.filename = filename metadata.status = 'Pending' metadata.uploader_email = uploader_email metadata.testcase_id = testcase_id metadata.blobstore_key = key metadata.original_blobstore_key = original_key metadata.timeout = timeout metadata.bundled = bundled metadata.retries = retries if bundled: metadata.path_in_archive = file_path_input metadata.timestamp = testcase.timestamp metadata.bug_summary_update_flag = bool(bug_summary_update_flag) metadata.put() # Create the job to analyze the testcase. tasks.add_task('analyze', testcase_id, job_type, queue) return testcase.key.id()
def test_unreproducible_get(self): """Test valid unreproducible testcase.""" self.mock.get_last_crash_time.return_value = datetime.datetime( 2000, 1, 1) testcase = data_types.Testcase() testcase.job_type = 'windows_asan_chrome' testcase.crash_type = 'crash_type1\ncrash_type2' testcase.crash_address = 'crash_address' testcase.crash_state = 'crash_state' testcase.crash_revision = 123 testcase.regression = None testcase.fixed = None testcase.fuzzed_keys = None testcase.minimized_keys = None testcase.timestamp = datetime.datetime(1970, 1, 1) testcase.project_name = 'chromium' testcase.one_time_crasher_flag = True testcase.put() job = data_types.Job() job.name = 'windows_asan_chrome' job.custom_binary_revision = 1234 job.put() self.mock.can_user_access_testcase.return_value = True self.mock.get_issue_url.return_value = 'issue_url' self.mock.get_stacktrace.return_value = 'crash_stacktrace' self.mock.filter_stacktrace.return_value = 'crash_stacktrace' self.mock.get_environment.return_value = ({'HELP_URL': 'help_url'}) self.mock.generate_csrf_token.return_value = 'csrf' result = show.get_testcase_detail_by_id(2) expected_subset = { 'id': 2, 'crash_type': 'crash_type1 crash_type2', 'crash_address': 'crash_address', 'crash_state': 'crash_state', 'crash_state_lines': ['crash_state'], 'crash_revision': 123, 'csrf_token': 'csrf', 'external_user': True, 'footer': '', 'fixed': 'NO', 'issue_url': 'issue_url', 'metadata': {}, 'minimized_testcase_size': '', 'needs_refresh': True, 'original_testcase_size': '', 'privileged_user': False, 'regression': 'Pending', 'security_severity': None, 'show_impact': False, 'show_blame': True, 'auto_delete_timestamp': 947289600.0, 'auto_close_timestamp': None, 'memory_tool_display_label': 'Sanitizer', 'memory_tool_display_value': 'address (ASAN)', 'last_tested': 'name: 0:revision<br />', 'is_admin_or_not_oss_fuzz': True, 'has_issue_tracker': True, 'reproduction_help_url': 'help_url', } self.maxDiff = None # pylint: disable=invalid-name self.assertDictContainsSubset(expected_subset, result) self.assertEqual(result['testcase'].key.id(), testcase.key.id()) self.assertDictContainsSubset( {'lines': [show.Line(1, 'crash_stacktrace', False)]}, result['crash_stacktrace']) self.assertDictContainsSubset( {'lines': [show.Line(1, 'crash_stacktrace', False)]}, result['second_crash_stacktrace']) self.assertDictContainsSubset( {'lines': [show.Line(1, 'crash_stacktrace', False)]}, result['last_tested_crash_stacktrace'])
def setUp(self): data_types.Job( name='job1', environment_string='ISSUE_VIEW_RESTRICTIONS = all', platform='linux').put() data_types.Job( name='job2', environment_string='ISSUE_VIEW_RESTRICTIONS = security', platform='linux').put() data_types.Job( name='job3', environment_string='ISSUE_VIEW_RESTRICTIONS = none', platform='linux').put() data_types.Job( name='chromeos_job4', environment_string='', platform='linux').put() testcase_args = { 'crash_type': 'Heap-use-after-free', 'crash_address': '0x1337', 'crash_state': '1\n2\n3\n', 'crash_stacktrace': 'stack\n', 'fuzzer_name': 'fuzzer', } self.testcase1 = data_types.Testcase(job_type='job1', **testcase_args) self.testcase1.put() self.testcase1_security = data_types.Testcase( security_flag=True, job_type='job1', **testcase_args) self.testcase1_security.put() self.testcase2 = data_types.Testcase(job_type='job2', **testcase_args) self.testcase2.put() self.testcase2_security = data_types.Testcase( security_flag=True, job_type='job2', **testcase_args) self.testcase2_security.put() self.testcase3 = data_types.Testcase(job_type='job3', **testcase_args) self.testcase3.put() self.testcase3_security = data_types.Testcase( job_type='job3', security_flag=True, **testcase_args) self.testcase3_security.put() self.testcase4 = data_types.Testcase( job_type='chromeos_job4', **testcase_args) self.testcase4.put() self.testcase5 = data_types.Testcase( job_type='job', additional_metadata='{"issue_labels": "label1 , label2,,"}', **testcase_args) self.testcase5.put() self.testcase6 = data_types.Testcase( job_type='job', additional_metadata='invalid', **testcase_args) self.testcase5.put() data_types.ExternalUserPermission( email='*****@*****.**', entity_name='job2', entity_kind=data_types.PermissionEntityKind.JOB, is_prefix=False, auto_cc=data_types.AutoCCType.ALL).put() data_types.ExternalUserPermission( email='*****@*****.**', entity_name='job3', entity_kind=data_types.PermissionEntityKind.JOB, is_prefix=False, auto_cc=data_types.AutoCCType.SECURITY).put() helpers.patch(self, [ 'base.utils.utcnow', 'datastore.data_handler.get_issue_description', ]) self.mock.get_issue_description.return_value = 'Issue' self.mock.utcnow.return_value = datetime.datetime(2016, 1, 1)
def setUp(self): helpers.patch_environ(self) project_config_get = local_config.ProjectConfig.get helpers.patch(self, [ 'base.utils.default_project_name', 'config.db_config.get', ('project_config_get', 'config.local_config.ProjectConfig.get'), ]) self.job = data_types.Job( name='linux_asan_chrome', environment_string=('SUMMARY_PREFIX = project\n' 'PROJECT_NAME = project\n' 'HELP_URL = help_url\n')) self.job2 = data_types.Job( name='windows_asan_chrome', environment_string=('SUMMARY_PREFIX = project\n' 'PROJECT_NAME = project\n' 'HELP_URL = help_url\n')) self.testcase = data_types.Testcase( job_type='linux_asan_chrome', fuzzer_name='libfuzzer_binary_name', crash_type='Crash-type', crash_address='0x1337', crash_state='A\nB\nC\n') self.testcase.set_metadata('fuzzer_binary_name', 'binary_name', update_testcase=False) self.testcase_assert = data_types.Testcase( job_type='linux_asan_chrome', fuzzer_name='libfuzzer_binary_name', crash_type='ASSERT', crash_address='0x1337', crash_state='foo != bar\nB\nC\n') self.testcase_assert.set_metadata('fuzzer_binary_name', 'binary_name', update_testcase=False) self.testcase_null = data_types.Testcase( job_type='linux_asan_chrome', fuzzer_name='libfuzzer_binary_name', crash_type='UNKNOWN', crash_address='0x1337', crash_state='NULL') self.testcase_bad_cast = data_types.Testcase( job_type='linux_asan_chrome', fuzzer_name='libfuzzer_binary_name', crash_type='Bad-cast', crash_address='0x1337', crash_state= ('Bad-cast to blink::LayoutBlock from blink::LayoutTableSection\n' 'blink::LayoutObject::ContainerForFixedPosition\n' 'blink::LayoutObject::Container\n')) self.testcase_bad_cast_without_crash_function = data_types.Testcase( job_type='linux_asan_chrome', fuzzer_name='libfuzzer_binary_name', crash_type='Bad-cast', crash_address='0x1337', crash_state= ('Bad-cast to blink::LayoutBlock from blink::LayoutTableSection\n' )) self.local_data_bundle = data_types.DataBundle( name='local_data_bundle') self.cloud_data_bundle = data_types.DataBundle( name='cloud_data_bundle') self.fuzzer1 = data_types.Fuzzer(name='fuzzer1', data_bundle_name=None, jobs=['linux_asan_chrome']) self.fuzzer2 = data_types.Fuzzer(name='fuzzer2', data_bundle_name='local_data_bundle', jobs=['linux_asan_chrome']) self.fuzzer3 = data_types.Fuzzer(name='fuzzer3', data_bundle_name='cloud_data_bundle', jobs=['linux_asan_chrome']) entities_to_put = [ self.testcase, self.testcase_assert, self.testcase_null, self.testcase_bad_cast, self.testcase_bad_cast_without_crash_function, self.job, self.job2, self.local_data_bundle, self.cloud_data_bundle, self.fuzzer1, self.fuzzer2, self.fuzzer3 ] for entity in entities_to_put: entity.put() environment.set_value('FUZZ_DATA', '/tmp/inputs/fuzzer-common-data-bundles') environment.set_value('FUZZERS_DIR', '/tmp/inputs/fuzzers') self.mock.default_project_name.return_value = 'project' self.mock.project_config_get.side_effect = project_config_get
def test_external_duplicate(self): """Test uploading a duplicate.""" existing = data_types.Testcase( crash_address='', crash_state='target\n', crash_type='Out-of-memory', project_name='proj', minimized_keys='NA', security_flag=False) existing.put() stacktrace = self._read_test_data('oom.txt') response = self.app.post( '/', params={ 'job': 'libfuzzer_proj_external', 'target': 'target', 'stacktrace': stacktrace, 'revision': 1337, }, upload_files=[('file', 'file', b'contents')]) self.assertDictEqual({ 'id': '3', 'uploadUrl': 'http://localhost//upload-testcase/upload-oauth' }, response.json) testcase = data_handler.get_testcase_by_id(3) self.assert_dict_has_items({ 'absolute_path': 'input', 'additional_metadata': '{"fuzzer_binary_name": "target", ' '"uploaded_additional_args": "%TESTCASE%"}', 'archive_filename': None, 'archive_state': 0, 'binary_flag': False, 'bug_information': '', 'comments': '[2021-01-01 00:00:00 UTC] uploader@email: ' 'External testcase upload.\n', 'crash_address': '', 'crash_revision': 1337, 'crash_stacktrace': stacktrace, 'crash_state': 'target\n', 'crash_type': 'Out-of-memory', 'disable_ubsan': False, 'duplicate_of': 2, 'fixed': 'NA', 'flaky_stack': False, 'fuzzed_keys': 'blob_key', 'fuzzer_name': 'libFuzzer', 'gestures': [], 'group_bug_information': 0, 'group_id': 0, 'has_bug_flag': False, 'http_flag': False, 'impact_beta_version': None, 'impact_beta_version_likely': False, 'impact_stable_version': None, 'impact_stable_version_likely': False, 'is_a_duplicate_flag': True, 'is_impact_set_flag': False, 'is_leader': False, 'job_type': 'libfuzzer_proj_external', 'last_tested_crash_stacktrace': None, 'minidump_keys': None, 'minimized_arguments': '', 'minimized_keys': 'NA', 'one_time_crasher_flag': False, 'open': False, 'overridden_fuzzer_name': 'libFuzzer_proj_target', 'platform': 'linux', 'platform_id': 'linux', 'project_name': 'proj', 'queue': None, 'redzone': 128, 'regression': 'NA', 'security_flag': False, 'security_severity': None, 'status': 'Duplicate', 'symbolized': False, 'timeout_multiplier': 1.0, 'timestamp': datetime.datetime(2021, 1, 1), 'triaged': True, 'uploader_email': 'uploader@email', 'window_argument': '' }, testcase._to_dict()) metadata = data_types.TestcaseUploadMetadata.query( data_types.TestcaseUploadMetadata.testcase_id == testcase.key.id()).get() self.assertIsNotNone(metadata) self.assertDictEqual({ 'additional_metadata_string': None, 'blobstore_key': 'blob_key', 'bot_name': None, 'bug_information': '', 'bug_summary_update_flag': False, 'bundled': False, 'duplicate_of': 2, 'filename': 'input', 'original_blobstore_key': 'blob_key', 'path_in_archive': None, 'quiet_flag': False, 'retries': None, 'security_flag': False, 'status': 'Duplicate', 'testcase_id': 3, 'timeout': 0, 'timestamp': datetime.datetime(2021, 1, 1, 0, 0), 'uploader_email': 'uploader@email' }, metadata._to_dict())
def store_testcase(crash, fuzzed_keys, minimized_keys, regression, fixed, one_time_crasher_flag, crash_revision, comment, absolute_path, fuzzer_name, fully_qualified_fuzzer_name, job_type, archived, archive_filename, binary_flag, http_flag, gestures, redzone, minidump_keys, window_argument, timeout_multiplier, minimized_arguments): """Create a testcase and store it in the datastore using remote api.""" # Initialize variable to prevent invalid values. if archived: archive_state = data_types.ArchiveStatus.FUZZED else: archive_state = 0 if not gestures: gestures = [] if not redzone: redzone = 128 # Create the testcase. testcase = data_types.Testcase() testcase.crash_type = crash.crash_type testcase.crash_address = crash.crash_address testcase.crash_state = utils.decode_to_unicode(crash.crash_state) testcase.crash_stacktrace = filter_stacktrace(crash.crash_stacktrace) testcase.fuzzed_keys = fuzzed_keys testcase.minimized_keys = minimized_keys testcase.bug_information = '' testcase.regression = regression testcase.fixed = fixed testcase.security_flag = crash.security_flag testcase.security_severity = _get_security_severity(crash, job_type, gestures) testcase.one_time_crasher_flag = one_time_crasher_flag testcase.crash_revision = crash_revision testcase.original_absolute_path = absolute_path testcase.absolute_path = absolute_path testcase.fuzzer_name = fuzzer_name testcase.overridden_fuzzer_name = fully_qualified_fuzzer_name or fuzzer_name testcase.job_type = job_type testcase.queue = tasks.default_queue() testcase.archive_state = archive_state testcase.archive_filename = archive_filename testcase.binary_flag = binary_flag testcase.http_flag = http_flag testcase.timestamp = datetime.datetime.utcnow() testcase.gestures = gestures testcase.redzone = redzone testcase.minidump_keys = minidump_keys testcase.window_argument = window_argument testcase.timeout_multiplier = float(timeout_multiplier) testcase.minimized_arguments = minimized_arguments testcase.project_name = get_project_name(job_type) # Set metadata fields (e.g. build url, build key, platform string, etc). set_initial_testcase_metadata(testcase) # Update the comment and save testcase. update_testcase_comment(testcase, data_types.TaskState.NA, comment) # Get testcase id from newly created testcase. testcase_id = testcase.key.id() logs.log( ('Created new testcase %d (reproducible:%s, security:%s, binary:%s).\n' 'crash_type: %s\ncrash_state:\n%s\n') % (testcase_id, not testcase.one_time_crasher_flag, testcase.security_flag, testcase.binary_flag, testcase.crash_type, testcase.crash_state)) # Update global blacklist to avoid finding this leak again (if needed). is_lsan_enabled = environment.get_value('LSAN') if is_lsan_enabled: from fuzzing import leak_blacklist leak_blacklist.add_crash_to_global_blacklist_if_needed(testcase) return testcase_id
def _add_dummy_leak_testcase(self): """Helper function to add a dummy testcase to Testcase database.""" testcase_item = data_types.Testcase(crash_type='Direct-leak', crash_state='test_foo\ntest_bar\n') testcase_item.put() return testcase_item
def setUp(self): helpers.patch_environ(self) self.testcase = data_types.Testcase() self.testcase.one_time_crasher_flag = False self.testcase.crash_state = 'fake_crash'