示例#1
0
    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',
            }
        })
示例#2
0
    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))
示例#3
0
    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()))
示例#4
0
    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()
示例#7
0
    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()))
示例#8
0
    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()
示例#9
0
    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)
示例#10
0
    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)
示例#11
0
  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',
        }
    })
示例#12
0
    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)
示例#13
0
    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'])
示例#14
0
    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()
示例#15
0
  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))
示例#16
0
    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\'')
示例#17
0
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()
示例#18
0
    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'])
示例#19
0
  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)
示例#20
0
    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
示例#21
0
  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())
示例#22
0
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
示例#23
0
 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
示例#24
0
 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'