Exemplo n.º 1
0
 def test_get_invalid_project(self):
   """Checks the latest build will return None when project doesn't exist."""
   test_target = fuzz_target.FuzzTarget('/example/path', 10, '/example/outdir',
                                        'not-a-proj')
   self.assertIsNone(test_target.get_lastest_build_version())
   test_target = fuzz_target.FuzzTarget('/example/path', 10, '/example/outdir')
   self.assertIsNone(test_target.get_lastest_build_version())
Exemplo n.º 2
0
 def test_get_invalid_project(self):
     """Tests the latest build returns None when project doesn't exist."""
     with tempfile.TemporaryDirectory() as tmp_dir:
         test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer',
                                              10, tmp_dir)
         self.assertIsNone(test_target.download_oss_fuzz_build())
         test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer',
                                              10, tmp_dir, 'not-a-proj')
         self.assertIsNone(test_target.download_oss_fuzz_build())
Exemplo n.º 3
0
 def test_download_invalid_projects_corpus(self):
     """Tests that a invaild fuzz target does not return None."""
     with tempfile.TemporaryDirectory() as tmp_dir:
         test_target = fuzz_target.FuzzTarget('testfuzzer', 3, tmp_dir)
         corpus_path = test_target.download_latest_corpus()
         self.assertIsNone(corpus_path)
         test_target = fuzz_target.FuzzTarget('not_a_fuzzer', 3, tmp_dir,
                                              'not_a_project')
         corpus_path = test_target.download_latest_corpus()
         self.assertIsNone(corpus_path)
Exemplo n.º 4
0
 def setUp(self):
     """Sets up example fuzz target to test get_testcase method."""
     deployment = _create_deployment()
     self.test_target = fuzz_target.FuzzTarget('/example/path', 10,
                                               '/example/outdir',
                                               deployment,
                                               deployment.config)
Exemplo n.º 5
0
 def test_invalid_build_dir(self):
     """Tests the download returns None when out_dir doesn't exist."""
     with tempfile.TemporaryDirectory() as tmp_dir:
         invalid_dir = os.path.join(tmp_dir, 'not/a/dir')
         test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer',
                                              10, invalid_dir, 'example')
         self.assertIsNone(test_target.download_oss_fuzz_build())
Exemplo n.º 6
0
 def setUp(self):
     """Sets up dummy fuzz target to test is_reproducible method."""
     self.fuzz_target_path = '/example/path'
     self.testcase_path = '/testcase'
     self.test_target = fuzz_target.FuzzTarget(
         self.fuzz_target_path, fuzz_target.REPRODUCE_ATTEMPTS,
         '/example/outdir')
Exemplo n.º 7
0
 def create_fuzz_target_obj(self, target_path, run_seconds):
     """Returns a fuzz target object."""
     return fuzz_target.FuzzTarget(target_path,
                                   run_seconds,
                                   self.out_dir,
                                   self.config.project_name,
                                   sanitizer=self.config.sanitizer)
Exemplo n.º 8
0
def run_fuzzers(config):  # pylint: disable=too-many-locals
    """Runs fuzzers for a specific OSS-Fuzz project.

  Args:
    fuzz_seconds: The total time allotted for fuzzing.
    workspace: The location in a shared volume to store a git repo and build
      artifacts.
    project_name: The name of the relevant OSS-Fuzz project.
    sanitizer: The sanitizer the fuzzers should be run with.

  Returns:
    (True if run was successful, True if bug was found).
  """
    # Validate inputs.
    logging.info('Using %s sanitizer.', config.sanitizer)

    out_dir = os.path.join(config.workspace, 'out')
    artifacts_dir = os.path.join(out_dir, 'artifacts')
    os.makedirs(artifacts_dir, exist_ok=True)

    if not config.fuzz_seconds or config.fuzz_seconds < 1:
        logging.error(
            'Fuzz_seconds argument must be greater than 1, but was: %s.',
            config.fuzz_seconds)
        return False, False

    # Get fuzzer information.
    fuzzer_paths = utils.get_fuzz_targets(out_dir)
    if not fuzzer_paths:
        logging.error('No fuzzers were found in out directory: %s.', out_dir)
        return False, False

    # Run fuzzers for allotted time.
    total_num_fuzzers = len(fuzzer_paths)
    fuzzers_left_to_run = total_num_fuzzers
    min_seconds_per_fuzzer = config.fuzz_seconds // total_num_fuzzers
    for fuzzer_path in fuzzer_paths:
        run_seconds = max(config.fuzz_seconds // fuzzers_left_to_run,
                          min_seconds_per_fuzzer)

        target = fuzz_target.FuzzTarget(fuzzer_path,
                                        run_seconds,
                                        out_dir,
                                        config.project_name,
                                        sanitizer=config.sanitizer)
        start_time = time.time()
        testcase, stacktrace = target.fuzz()
        config.fuzz_seconds -= (time.time() - start_time)
        if not testcase or not stacktrace:
            logging.info('Fuzzer %s, finished running.', target.target_name)
        else:
            utils.binary_print(b'Fuzzer %s, detected error:\n%s' %
                               (target.target_name.encode(), stacktrace))
            shutil.move(testcase, os.path.join(artifacts_dir, 'test_case'))
            stack_parser.parse_fuzzer_output(stacktrace, artifacts_dir)
            return True, True
        fuzzers_left_to_run -= 1

    return True, False
Exemplo n.º 9
0
 def test_get_valid_project(self):
     """Tests that the latest build can be retrieved from GCS."""
     test_target = fuzz_target.FuzzTarget('/example/path', 10,
                                          '/example/outdir', 'example')
     latest_build = test_target.get_lastest_build_version()
     self.assertIsNotNone(latest_build)
     self.assertTrue(latest_build.endswith('.zip'))
     self.assertTrue('address' in latest_build)
Exemplo n.º 10
0
 def test_get_valid_project(self):
     """Tests the latest build can be retrieved from GCS."""
     with tempfile.TemporaryDirectory() as tmp_dir:
         test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer',
                                              10, tmp_dir, 'example')
         oss_fuzz_build_path = test_target.download_oss_fuzz_build()
         self.assertIsNotNone(oss_fuzz_build_path)
         self.assertTrue(os.listdir(oss_fuzz_build_path))
Exemplo n.º 11
0
 def setUp(self):
     """Sets up example fuzz target to test is_reproducible method."""
     self.fuzz_target_path = '/example/path'
     self.testcase_path = '/testcase'
     deployment = _create_deployment()
     self.test_target = fuzz_target.FuzzTarget(
         self.fuzz_target_path, fuzz_target.REPRODUCE_ATTEMPTS,
         '/example/outdir', deployment, deployment.config)
Exemplo n.º 12
0
 def setUp(self):
     """Sets up example fuzz target to test is_reproducible method."""
     self.setUpPyfakefs()
     deployment = _create_deployment()
     config = deployment.config
     workspace = deployment.workspace
     self.fuzz_target = fuzz_target.FuzzTarget('/path/fuzz-target', 10,
                                               workspace, deployment,
                                               config)
Exemplo n.º 13
0
def run_fuzzers(fuzz_seconds, workspace, project_name):
    """Runs all fuzzers for a specific OSS-Fuzz project.

  Args:
    fuzz_seconds: The total time allotted for fuzzing.
    workspace: The location in a shared volume to store a git repo and build
      artifacts.
    project_name: The name of the relevant OSS-Fuzz project.

  Returns:
    (True if run was successful, True if bug was found).
  """
    # Validate inputs.
    if not os.path.exists(workspace):
        logging.error('Invalid workspace: %s.', workspace)
        return False, False
    out_dir = os.path.join(workspace, 'out')
    artifacts_dir = os.path.join(out_dir, 'artifacts')
    os.makedirs(artifacts_dir, exist_ok=True)
    if not fuzz_seconds or fuzz_seconds < 1:
        logging.error(
            'Fuzz_seconds argument must be greater than 1, but was: %s.',
            format(fuzz_seconds))
        return False, False

    # Get fuzzer information.
    fuzzer_paths = utils.get_fuzz_targets(out_dir)
    if not fuzzer_paths:
        logging.error('No fuzzers were found in out directory: %s.',
                      format(out_dir))
        return False, False

    # Run fuzzers for alotted time.
    total_num_fuzzers = len(fuzzer_paths)
    fuzzers_left_to_run = total_num_fuzzers
    min_seconds_per_fuzzer = fuzz_seconds // total_num_fuzzers
    for fuzzer_path in fuzzer_paths:
        run_seconds = max(fuzz_seconds // fuzzers_left_to_run,
                          min_seconds_per_fuzzer)

        target = fuzz_target.FuzzTarget(fuzzer_path, run_seconds, out_dir,
                                        project_name)
        start_time = time.time()
        test_case, stack_trace = target.fuzz()
        fuzz_seconds -= (time.time() - start_time)
        if not test_case or not stack_trace:
            logging.info('Fuzzer %s, finished running.', target.target_name)
        else:
            logging.info('Fuzzer %s, detected error: %s.', target.target_name,
                         stack_trace)
            shutil.move(test_case, os.path.join(artifacts_dir, 'test_case'))
            parse_fuzzer_output(stack_trace, artifacts_dir)
            return True, True
        fuzzers_left_to_run -= 1

    return True, False
Exemplo n.º 14
0
 def setUp(self):
   """Sets up example fuzz target to test is_reproducible method."""
   self.fuzz_target_name = 'fuzz-target'
   deployment = _create_deployment()
   self.workspace = deployment.workspace
   self.fuzz_target_path = os.path.join(self.workspace.out,
                                        self.fuzz_target_name)
   self.testcase_path = '/testcase'
   self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path,
                                             fuzz_target.REPRODUCE_ATTEMPTS,
                                             self.workspace, deployment,
                                             deployment.config)
Exemplo n.º 15
0
 def setUp(self):
     """Sets up dummy fuzz target to test is_crash_reportable method."""
     self.fuzz_target_path = '/example/do_stuff_fuzzer'
     self.test_target = fuzz_target.FuzzTarget(self.fuzz_target_path, 100,
                                               '/example/outdir', 'example')
     self.oss_fuzz_build_path = '/oss-fuzz-build'
     self.setUpPyfakefs()
     self.fs.create_file(self.fuzz_target_path)
     self.oss_fuzz_target_path = os.path.join(
         self.oss_fuzz_build_path, os.path.basename(self.fuzz_target_path))
     self.fs.create_file(self.oss_fuzz_target_path)
     self.testcase_path = '/testcase'
     self.fs.create_file(self.testcase_path, contents='')
Exemplo n.º 16
0
 def test_single_download(self):
   """Tests that the build directory was only downloaded once."""
   with tempfile.TemporaryDirectory() as tmp_dir:
     test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                          tmp_dir, 'example')
     latest_version = test_target.get_lastest_build_version()
     with unittest.mock.patch(
         'fuzz_target.FuzzTarget.get_lastest_build_version',
         return_value=latest_version) as mocked_get_latest_build_version:
       for _ in range(5):
         oss_fuzz_build_path = test_target.download_oss_fuzz_build()
       self.assertEqual(1, mocked_get_latest_build_version.call_count)
       self.assertIsNotNone(oss_fuzz_build_path)
       self.assertTrue(os.listdir(oss_fuzz_build_path))
Exemplo n.º 17
0
    def setUp(self):
        """Sets up example fuzz target to test is_crash_reportable method."""
        self.setUpPyfakefs()
        self.fuzz_target_path = '/example/do_stuff_fuzzer'
        deployment = _create_deployment()
        self.target = fuzz_target.FuzzTarget(self.fuzz_target_path, 100,
                                             deployment.workspace, deployment,
                                             deployment.config)
        self.oss_fuzz_build_path = '/oss-fuzz-build'
        self.fs.create_file(self.fuzz_target_path)
        self.oss_fuzz_target_path = os.path.join(
            self.oss_fuzz_build_path, os.path.basename(self.fuzz_target_path))
        self.fs.create_file(self.oss_fuzz_target_path)
        self.testcase_path = '/testcase'
        self.fs.create_file(self.testcase_path, contents='')

        # Do this to prevent pyfakefs from messing with requests.
        self.fs.add_real_directory(os.path.dirname(certifi.__file__))
Exemplo n.º 18
0
 def test_download_valid_projects_corpus(self):
   """Tests that a vaild fuzz target returns a corpus directory."""
   with tempfile.TemporaryDirectory() as tmp_dir:
     test_target = fuzz_target.FuzzTarget('testfuzzer', 3, 'test_out')
     test_target.project_name = EXAMPLE_PROJECT
     test_target.target_name = EXAMPLE_FUZZER
     test_target.out_dir = tmp_dir
     with unittest.mock.patch(
         'fuzz_target.download_and_unpack_zip',
         return_value=tmp_dir) as mocked_download_and_unpack_zip:
       test_target.download_latest_corpus()
       (url, out_dir), _ = mocked_download_and_unpack_zip.call_args
       self.assertEqual(
           url, 'https://storage.googleapis.com/example-backup.'
           'clusterfuzz-external.appspot.com/corpus/libFuzzer/'
           'example_crash_fuzzer/public.zip')
       self.assertEqual(out_dir,
                        os.path.join(tmp_dir, 'backup_corpus', EXAMPLE_FUZZER))
Exemplo n.º 19
0
def run_fuzzers(project_name, fuzz_seconds, workspace):
    """Runs all fuzzers for a specific OSS-Fuzz project.

  Args:
    project_name: The name of the OSS-Fuzz project being built.
    fuzz_seconds: The total time allotted for fuzzing.
    workspace: The location in a shared volume to store a git repo and build
      artifacts.

  Returns:
    (True if run was successful, True if bug was found).
  """
    # Validate inputs.
    if not os.path.exists(workspace):
        logging.error('Invalid workspace: %s.', workspace)
        return False, False
    out_dir = os.path.join(workspace, 'out')
    if not fuzz_seconds or fuzz_seconds < 1:
        logging.error(
            'Fuzz_seconds argument must be greater than 1, but was: %s.',
            format(fuzz_seconds))
        return False, False

    # Get fuzzer information.
    fuzzer_paths = utils.get_fuzz_targets(out_dir)
    if not fuzzer_paths:
        logging.error('No fuzzers were found in out directory: %s.',
                      format(out_dir))
        return False, False
    fuzz_seconds_per_target = fuzz_seconds // len(fuzzer_paths)

    # Run fuzzers for alotted time.
    for fuzzer_path in fuzzer_paths:
        target = fuzz_target.FuzzTarget(project_name, fuzzer_path,
                                        fuzz_seconds_per_target, out_dir)
        test_case, stack_trace = target.fuzz()
        if not test_case or not stack_trace:
            logging.info('Fuzzer %s, finished running.', target.target_name)
        else:
            logging.info('Fuzzer %s, detected error: %s.', target.target_name,
                         stack_trace)
            shutil.move(test_case, os.path.join(out_dir, 'testcase'))
            return True, True
    return True, False
Exemplo n.º 20
0
    def setUp(self):
        """Sets up example fuzz target to test is_reproducible method."""
        self.fuzz_target_name = 'fuzz-target'
        deployment = _create_deployment()
        self.config = deployment.config
        self.workspace = deployment.workspace
        self.fuzz_target_path = os.path.join(self.workspace.out,
                                             self.fuzz_target_name)
        self.setUpPyfakefs()
        self.fs.create_file(self.fuzz_target_path)
        self.testcase_path = '/testcase'
        self.fs.create_file(self.testcase_path)

        self.target = fuzz_target.FuzzTarget(self.fuzz_target_path,
                                             fuzz_target.REPRODUCE_ATTEMPTS,
                                             self.workspace, deployment,
                                             deployment.config)

        test_helpers.patch_environ(self, empty=True)
Exemplo n.º 21
0
 def test_timeout_reported(self, report_timeouts, expect_crash):
     """Tests that timeouts are not reported."""
     with test_helpers.temp_dir_copy(TEST_DATA_PATH) as temp_dir:
         fuzz_target_path = os.path.join(temp_dir, 'build-out',
                                         self.TIMEOUT_FUZZER_NAME)
         shutil.copy(os.path.join(temp_dir, self.TIMEOUT_FUZZER_NAME),
                     fuzz_target_path)
         deployment = _create_deployment(workspace=temp_dir,
                                         report_timeouts=report_timeouts)
         config = deployment.config
         fuzz_target_obj = fuzz_target.FuzzTarget(
             fuzz_target_path, fuzz_target.REPRODUCE_ATTEMPTS,
             deployment.workspace, deployment, config)
         with mock.patch('clusterfuzz._internal.bot.fuzzers.libfuzzer.'
                         'fix_timeout_argument_for_reproduction') as _:
             with mock.patch(
                     'clusterfuzz._internal.bot.fuzzers.libFuzzer.fuzzer.get_arguments',
                     return_value=['-timeout=1', '-rss_limit_mb=2560']):
                 fuzz_result = fuzz_target_obj.fuzz()
     self.assertEqual(bool(fuzz_result.testcase), expect_crash)
Exemplo n.º 22
0
 def test_invalid_build_dir(self):
     """Tests the download returns None when out_dir doesn't exist."""
     test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 10,
                                          'not/a/dir', 'example')
     self.assertIsNone(test_target.download_oss_fuzz_build())
Exemplo n.º 23
0
 def create_fuzz_target_obj(self, target_path, run_seconds):
   """Returns a fuzz target object."""
   return fuzz_target.FuzzTarget(target_path, run_seconds, self.out_dir,
                                 self.clusterfuzz_deployment, self.config)
Exemplo n.º 24
0
 def setUp(self):
   """Sets up dummy fuzz target to test is_reproducible method."""
   self.test_target = fuzz_target.FuzzTarget('/example/do_stuff_fuzzer', 100,
                                             '/example/outdir', 'example')
Exemplo n.º 25
0
 def setUp(self):
     """Sets up dummy fuzz target to test get_test_case method."""
     self.test_target = fuzz_target.FuzzTarget('/example/path', 10,
                                               '/example/outdir')