Example #1
0
    def test_reproduce(self):
        """Test reproduce."""
        testcase_file_path = os.path.join(self.temp_dir, 'testcase')
        with open(testcase_file_path, 'wb') as f:
            f.write(b'EEE')

        self._setup_env(job_type='libfuzzer_asan_job')

        build_manager.setup_build()
        result = testcase_manager.engine_reproduce(libfuzzer_engine.Engine(),
                                                   'test_fuzzer',
                                                   testcase_file_path, [], 30)

        self.assertEqual([
            os.path.join(environment.get_value('BUILD_DIR'), 'test_fuzzer'),
            '-runs=100',
            file_host.rebase_to_worker_root(testcase_file_path)
        ], result.command)
        self.assertEqual(result.return_code,
                         libfuzzer_constants.TARGET_ERROR_EXITCODE)
        self.assertGreater(result.time_executed, 0)
        self.assertIn('Running 1 inputs 100 time(s) each', result.output)
        self.assertIn(
            'AddressSanitizer: SEGV on unknown address 0x000000000000',
            result.output)
  def test_target_not_found(self):
    """Test target not found."""
    testcase_file_path = os.path.join(self.temp_dir, 'testcase')
    with open(testcase_file_path, 'wb') as f:
      f.write(b'EEE')

    self._setup_env(job_type='libfuzzer_asan_job')

    build_manager.setup_build()
    with self.assertRaises(testcase_manager.TargetNotFoundError):
      testcase_manager.engine_reproduce(libfuzzer_engine.Engine(),
                                        'does_not_exist', testcase_file_path,
                                        [], 30)
    def setUp(self):
        """Setup."""
        helpers.patch_environ(self)
        helpers.patch(self, [
            'clusterfuzz._internal.bot.fuzzers.engine_common.unpack_seed_corpus_if_needed',
            'clusterfuzz._internal.bot.tasks.corpus_pruning_task.'
            'choose_cross_pollination_strategy',
            'clusterfuzz._internal.bot.tasks.task_creation.create_tasks',
            'clusterfuzz._internal.bot.tasks.setup.update_fuzzer_and_data_bundles',
            'clusterfuzz._internal.fuzzing.corpus_manager.backup_corpus',
            'clusterfuzz._internal.fuzzing.corpus_manager.GcsCorpus.rsync_to_disk',
            'clusterfuzz._internal.fuzzing.corpus_manager.FuzzTargetCorpus.rsync_from_disk',
            'clusterfuzz._internal.google_cloud_utils.blobs.write_blob',
            'clusterfuzz._internal.google_cloud_utils.storage.write_data',
            'clusterfuzz.fuzz.engine.get',
        ])
        self.mock.get.return_value = libFuzzer_engine.Engine()
        self.mock.rsync_to_disk.side_effect = self._mock_rsync_to_disk
        self.mock.rsync_from_disk.side_effect = self._mock_rsync_from_disk
        self.mock.update_fuzzer_and_data_bundles.return_value = True
        self.mock.write_blob.return_value = 'key'
        self.mock.backup_corpus.return_value = 'backup_link'
        self.mock.choose_cross_pollination_strategy.return_value = ('random',
                                                                    None)

        def mocked_unpack_seed_corpus_if_needed(*args, **kwargs):
            """Mock's assert called methods are not powerful enough to ensure that
      unpack_seed_corpus_if_needed was called once with force_unpack=True.
      Instead, just assert that it was called once and during the call assert
      that it was called correctly.
      """
            self.assertTrue(kwargs.get('force_unpack', False))

        self.mock.unpack_seed_corpus_if_needed.side_effect = (
            mocked_unpack_seed_corpus_if_needed)

        data_types.FuzzTarget(engine='libFuzzer',
                              binary='test_fuzzer',
                              project='test-project').put()
        data_types.FuzzTargetJob(fuzz_target_name='libFuzzer_test_fuzzer',
                                 engine='libFuzzer',
                                 job='libfuzzer_asan_job').put()

        self.fuzz_inputs_disk = tempfile.mkdtemp()
        self.bot_tmpdir = tempfile.mkdtemp()
        self.build_dir = os.path.join(TEST_DIR, 'build')
        self.corpus_bucket = tempfile.mkdtemp()
        self.corpus_dir = os.path.join(self.corpus_bucket, 'corpus')
        self.quarantine_dir = os.path.join(self.corpus_bucket, 'quarantine')
        self.shared_corpus_dir = os.path.join(self.corpus_bucket, 'shared')

        shutil.copytree(os.path.join(TEST_DIR, 'corpus'), self.corpus_dir)
        shutil.copytree(os.path.join(TEST_DIR, 'quarantine'),
                        self.quarantine_dir)
        shutil.copytree(os.path.join(TEST_DIR, 'shared'),
                        self.shared_corpus_dir)

        os.environ['BOT_TMPDIR'] = self.bot_tmpdir
        os.environ['FUZZ_INPUTS'] = self.fuzz_inputs_disk
        os.environ['FUZZ_INPUTS_DISK'] = self.fuzz_inputs_disk
        os.environ['CORPUS_BUCKET'] = 'bucket'
        os.environ['QUARANTINE_BUCKET'] = 'bucket-quarantine'
        os.environ['SHARED_CORPUS_BUCKET'] = 'bucket-shared'
        os.environ['JOB_NAME'] = 'libfuzzer_asan_job'
        os.environ['FAIL_RETRIES'] = '1'
        os.environ['APP_REVISION'] = '1337'
    def setUp(self):
        """Set up."""
        super(CorpusPruningTestUntrusted, self).setUp()
        environment.set_value('JOB_NAME', 'libfuzzer_asan_job')

        helpers.patch(self, [
            'clusterfuzz._internal.bot.tasks.setup.get_fuzzer_directory',
            'clusterfuzz._internal.base.tasks.add_task',
            'clusterfuzz._internal.bot.tasks.corpus_pruning_task.'
            '_record_cross_pollination_stats',
            'clusterfuzz.fuzz.engine.get',
        ])

        self.mock.get.return_value = libFuzzer_engine.Engine()
        self.mock.get_fuzzer_directory.return_value = os.path.join(
            environment.get_value('ROOT_DIR'), 'src', 'clusterfuzz',
            '_internal', 'bot', 'fuzzers', 'libFuzzer')
        self.corpus_bucket = os.environ['CORPUS_BUCKET']
        self.quarantine_bucket = os.environ['QUARANTINE_BUCKET']
        self.backup_bucket = os.environ['BACKUP_BUCKET']

        job = data_types.Job(
            name='libfuzzer_asan_job',
            environment_string=(
                'APP_NAME = test_fuzzer\n'
                'CORPUS_BUCKET = {corpus_bucket}\n'
                'QUARANTINE_BUCKET = {quarantine_bucket}\n'
                'BACKUP_BUCKET={backup_bucket}\n'
                'RELEASE_BUILD_BUCKET_PATH = '
                'gs://clusterfuzz-test-data/test_libfuzzer_builds/'
                'test-libfuzzer-build-([0-9]+).zip\n'
                'REVISION_VARS_URL = gs://clusterfuzz-test-data/'
                'test_libfuzzer_builds/'
                'test-libfuzzer-build-%s.srcmap.json\n'.format(
                    corpus_bucket=self.corpus_bucket,
                    quarantine_bucket=self.quarantine_bucket,
                    backup_bucket=self.backup_bucket)))
        job.put()

        job = data_types.Job(
            name='libfuzzer_asan_job2',
            environment_string=(
                'APP_NAME = test2_fuzzer\n'
                'BACKUP_BUCKET = {backup_bucket}\n'
                'CORPUS_FUZZER_NAME_OVERRIDE = libfuzzer\n'.format(
                    backup_bucket=self.backup_bucket)))
        job.put()

        os.environ['PROJECT_NAME'] = 'oss-fuzz'
        data_types.FuzzTarget(engine='libFuzzer',
                              project='test',
                              binary='test_fuzzer').put()
        data_types.FuzzTargetJob(fuzz_target_name='libFuzzer_test_fuzzer',
                                 engine='libFuzzer',
                                 job='libfuzzer_asan_job',
                                 last_run=datetime.datetime.now()).put()

        data_types.FuzzTarget(engine='libFuzzer',
                              project='test2',
                              binary='fuzzer').put()
        data_types.FuzzTargetJob(fuzz_target_name='libFuzzer_test2_fuzzer',
                                 engine='libFuzzer',
                                 job='libfuzzer_asan_job2',
                                 last_run=datetime.datetime.now()).put()

        environment.set_value('USE_MINIJAIL', True)
        environment.set_value('SHARED_CORPUS_BUCKET', TEST_SHARED_BUCKET)

        # Set up remote corpora.
        self.corpus = corpus_manager.FuzzTargetCorpus('libFuzzer',
                                                      'test_fuzzer')
        self.corpus.rsync_from_disk(os.path.join(TEST_DIR, 'corpus'),
                                    delete=True)

        self.quarantine_corpus = corpus_manager.FuzzTargetCorpus(
            'libFuzzer', 'test_fuzzer', quarantine=True)
        self.quarantine_corpus.rsync_from_disk(os.path.join(
            TEST_DIR, 'quarantine'),
                                               delete=True)

        self.mock.get_data_bundle_bucket_name.return_value = TEST_GLOBAL_BUCKET
        data_types.DataBundle(name='bundle',
                              is_local=True,
                              sync_to_worker=True).put()

        data_types.Fuzzer(revision=1,
                          file_size='builtin',
                          source='builtin',
                          name='libFuzzer',
                          max_testcases=4,
                          builtin=True,
                          data_bundle_name='bundle').put()

        self.temp_dir = tempfile.mkdtemp()

        # Copy corpus backup in the older date format.
        corpus_backup_date = (
            datetime.datetime.utcnow().date() - datetime.timedelta(
                days=data_types.CORPUS_BACKUP_PUBLIC_LOOKBACK_DAYS))
        corpus_backup_dir = ('gs://{bucket}/corpus/libfuzzer/test2_fuzzer/')
        gsutil.GSUtilRunner().run_gsutil([
            'cp', (corpus_backup_dir +
                   'backup.zip').format(bucket=TEST2_BACKUP_BUCKET),
            (corpus_backup_dir +
             '%s.zip' % corpus_backup_date).format(bucket=self.backup_bucket)
        ])