Example #1
0
 def test_invalid_filepath(self):
     """Tests what get_fuzz_targets return when invalid filepath is used."""
     utils.chdir_to_root()
     helper.build_fuzzers_impl(EXAMPLE_PROJECT,
                               True,
                               'libfuzzer',
                               'address',
                               'x86_64', [],
                               None,
                               no_cache=False,
                               mount_location=None)
     fuzz_targets = utils.get_fuzz_targets('not/a/valid/file/path')
     self.assertFalse(fuzz_targets)
Example #2
0
def build_fuzzer_from_commit(project_name,
                             commit,
                             local_store_path,
                             engine='libfuzzer',
                             sanitizer='address',
                             architecture='x86_64',
                             old_repo_manager=None):
    """Builds a OSS-Fuzz fuzzer at a  specific commit SHA.

  Args:
    project_name: The OSS-Fuzz project name
    commit: The commit SHA to build the fuzzers at
    local_store_path: The full file path of a place where a temp git repo is stored
    engine: The fuzzing engine to be used
    sanitizer: The fuzzing sanitizer to be used
    architecture: The system architiecture to be used for fuzzing

  Returns:
    0 on successful build 1 on failure
  """
    if not old_repo_manager:
        inferred_url = infer_main_repo(project_name, local_store_path, commit)
        old_repo_manager = repo_manager.RepoManager(inferred_url,
                                                    local_store_path)
    old_repo_manager.checkout_commit(commit)
    return helper.build_fuzzers_impl(project_name=project_name,
                                     clean=True,
                                     engine=engine,
                                     sanitizer=sanitizer,
                                     architecture=architecture,
                                     env_to_add=None,
                                     source_path=old_repo_manager.repo_dir)
def build_fuzzers_from_commit(commit, build_repo_manager, host_src_path,
                              build_data):
  """Builds a OSS-Fuzz fuzzer at a specific commit SHA.

  Args:
    commit: The commit SHA to build the fuzzers at.
    build_repo_manager: The OSS-Fuzz project's repo manager to be built at.
    build_data: A struct containing project build information.
  Returns:
    0 on successful build or error code on failure.
  """
  oss_fuzz_repo_manager = repo_manager.BaseRepoManager(helper.OSS_FUZZ_DIR)
  num_retry = 1

  for i in range(num_retry + 1):
    build_repo_manager.checkout_commit(commit, clean=False)
    result = helper.build_fuzzers_impl(project_name=build_data.project_name,
                                       clean=True,
                                       engine=build_data.engine,
                                       sanitizer=build_data.sanitizer,
                                       architecture=build_data.architecture,
                                       env_to_add=None,
                                       source_path=host_src_path,
                                       mount_location='/src')
    if result == 0 or i == num_retry:
      break

    # Retry with an OSS-Fuzz builder container that's closer to the project
    # commit date.
    commit_date = build_repo_manager.commit_date(commit)
    projects_dir = os.path.join('projects', build_data.project_name)

    # Find first change in the projects/<PROJECT> directory before the project
    # commit date.
    oss_fuzz_commit, _, _ = oss_fuzz_repo_manager.git([
        'log', '--before=' + commit_date.isoformat(), '-n1', '--format=%H',
        projects_dir
    ],
                                                      check_result=True)
    oss_fuzz_commit = oss_fuzz_commit.strip()
    if not oss_fuzz_commit:
      logging.warning('No suitable earlier OSS-Fuzz commit found.')
      break

    logging.info('Build failed. Retrying on earlier OSS-Fuzz commit %s.',
                 oss_fuzz_commit)

    # Check out projects/<PROJECT> dir to the commit that was found.
    oss_fuzz_repo_manager.git(['checkout', oss_fuzz_commit, projects_dir],
                              check_result=True)

    # Rebuild image and re-copy src dir since things in /src could have changed.
    if not helper.build_image_impl(build_data.project_name):
      raise RuntimeError('Failed to rebuild image.')

    shutil.rmtree(host_src_path, ignore_errors=True)
    copy_src_from_docker(build_data.project_name,
                         os.path.dirname(host_src_path))

  return result == 0
Example #4
0
 def test_valid_filepath(self):
     """Checks is_fuzz_target_local function with a valid filepath."""
     utils.chdir_to_root()
     helper.build_fuzzers_impl(EXAMPLE_PROJECT,
                               True,
                               'libfuzzer',
                               'address',
                               'x86_64', [],
                               None,
                               no_cache=False,
                               mount_location=None)
     is_local = utils.is_fuzz_target_local(
         os.path.join(helper.OSSFUZZ_DIR, 'build', 'out', EXAMPLE_PROJECT,
                      'do_stuff_fuzzer'))
     self.assertTrue(is_local)
     is_local = utils.is_fuzz_target_local(
         os.path.join(helper.OSSFUZZ_DIR, 'build', 'out', EXAMPLE_PROJECT,
                      'do_stuff_fuzzer.dict'))
     self.assertFalse(is_local)
Example #5
0
 def test_valid_filepath(self):
     """Tests that fuzz targets can be retrieved once the fuzzers are built."""
     utils.chdir_to_root()
     helper.build_fuzzers_impl(EXAMPLE_PROJECT,
                               True,
                               'libfuzzer',
                               'address',
                               'x86_64', [],
                               None,
                               no_cache=False,
                               mount_location=None)
     fuzz_targets = utils.get_fuzz_targets(
         os.path.join(helper.OSSFUZZ_DIR, 'build', 'out', EXAMPLE_PROJECT))
     self.assertCountEqual(fuzz_targets, [
         os.path.join(helper.OSSFUZZ_DIR, 'build', 'out', EXAMPLE_PROJECT,
                      'do_stuff_fuzzer')
     ])
     fuzz_targets = utils.get_fuzz_targets(
         os.path.join(helper.OSSFUZZ_DIR, 'infra'))
     self.assertFalse(fuzz_targets)
Example #6
0
def build_fuzzers_from_commit(commit, build_repo_manager, build_data):
    """Builds a OSS-Fuzz fuzzer at a  specific commit SHA.

  Args:
    commit: The commit SHA to build the fuzzers at.
    build_repo_manager: The OSS-Fuzz project's repo manager to be built at.
    build_data: A struct containing project build information.
  Returns:
    0 on successful build or error code on failure.
  """
    build_repo_manager.checkout_commit(commit)
    return helper.build_fuzzers_impl(project_name=build_data.project_name,
                                     clean=True,
                                     engine=build_data.engine,
                                     sanitizer=build_data.sanitizer,
                                     architecture=build_data.architecture,
                                     env_to_add=None,
                                     source_path=build_repo_manager.repo_dir,
                                     mount_location=os.path.join(
                                         '/src', build_repo_manager.repo_name))
Example #7
0
def build_fuzzer_from_commit(project_name,
                             commit,
                             local_store_path,
                             engine='libfuzzer',
                             sanitizer='address',
                             architecture='x86_64'):
    """Builds a ossfuzz fuzzer at a  specific commit SHA.

  Args:
    project_name: The oss fuzz project name
    commit: The commit SHA to build the fuzzers at
    local_store_path: The full file path of a place where a temp git repo is stored
    engine: The fuzzing engine to be used
    sanitizer: The fuzzing sanitizer to be used
    architecture: The system architiecture to be used for fuzzing

  Returns:
    0 on successful build 1 on failure
  """
    guessed_url = infer_main_repo(project_name, local_store_path, commit)
    repo_man = RepoManager(guessed_url, local_store_path)
    repo_man.checkout_commit(commit)
    return build_fuzzers_impl(project_name, True, engine, sanitizer,
                              architecture, None, repo_man.repo_dir)
Example #8
0
def build_fuzzers_from_commit(commit,
                              build_repo_manager,
                              host_src_path,
                              build_data,
                              base_builder_repo=None):
  """Builds a OSS-Fuzz fuzzer at a specific commit SHA.

  Args:
    commit: The commit SHA to build the fuzzers at.
    build_repo_manager: The OSS-Fuzz project's repo manager to be built at.
    build_data: A struct containing project build information.
    base_builder_repo: A BaseBuilderRepo.
  Returns:
    0 on successful build or error code on failure.
  """
  oss_fuzz_repo_manager = repo_manager.RepoManager(helper.OSS_FUZZ_DIR)
  num_retry = 1

  def cleanup():
    # Re-copy /src for a clean checkout every time.
    copy_src_from_docker(build_data.project_name,
                         os.path.dirname(host_src_path))

  projects_dir = os.path.join('projects', build_data.project_name)
  dockerfile_path = os.path.join(projects_dir, 'Dockerfile')

  for i in range(num_retry + 1):
    build_repo_manager.checkout_commit(commit, clean=False)

    post_checkout_steps = get_required_post_checkout_steps(dockerfile_path)
    for workdir, post_checkout_step in post_checkout_steps:
      logging.info('Running post-checkout step `%s` in %s.', post_checkout_step,
                   workdir)
      helper.docker_run([
          '-w',
          workdir,
          '-v',
          host_src_path + ':' + '/src',
          'gcr.io/oss-fuzz/' + build_data.project_name,
          '/bin/bash',
          '-c',
          post_checkout_step,
      ])

    result = helper.build_fuzzers_impl(project_name=build_data.project_name,
                                       clean=True,
                                       engine=build_data.engine,
                                       sanitizer=build_data.sanitizer,
                                       architecture=build_data.architecture,
                                       env_to_add=None,
                                       source_path=host_src_path,
                                       mount_location='/src')
    if result == 0 or i == num_retry:
      break

    # Retry with an OSS-Fuzz builder container that's closer to the project
    # commit date.
    commit_date = build_repo_manager.commit_date(commit)

    # Find first change in the projects/<PROJECT> directory before the project
    # commit date.
    oss_fuzz_commit, _, _ = oss_fuzz_repo_manager.git([
        'log', '--before=' + commit_date.isoformat(), '-n1', '--format=%H',
        projects_dir
    ],
                                                      check_result=True)
    oss_fuzz_commit = oss_fuzz_commit.strip()
    if not oss_fuzz_commit:
      logging.info(
          'Could not find first OSS-Fuzz commit prior to upstream commit. '
          'Falling back to oldest integration commit.')

      # Find the oldest commit.
      oss_fuzz_commit, _, _ = oss_fuzz_repo_manager.git(
          ['log', '--reverse', '--format=%H', projects_dir], check_result=True)

      oss_fuzz_commit = oss_fuzz_commit.splitlines()[0].strip()

    if not oss_fuzz_commit:
      logging.error('Failed to get oldest integration commit.')
      break

    logging.info('Build failed. Retrying on earlier OSS-Fuzz commit %s.',
                 oss_fuzz_commit)

    # Check out projects/<PROJECT> dir to the commit that was found.
    oss_fuzz_repo_manager.git(['checkout', oss_fuzz_commit, projects_dir],
                              check_result=True)

    # Also use the closest base-builder we can find.
    if base_builder_repo:
      base_builder_digest = base_builder_repo.find_digest(commit_date)
      logging.info('Using base-builder with digest %s.', base_builder_digest)
      _replace_base_builder_digest(dockerfile_path, base_builder_digest)

    # Rebuild image and re-copy src dir since things in /src could have changed.
    if not _build_image_with_retries(build_data.project_name):
      raise RuntimeError('Failed to rebuild image.')

    cleanup()

  cleanup()
  return result == 0