Beispiel #1
0
  def test_build_fuzzers_from_commit(self):
    """Tests if the fuzzers can build at a proper commit.

    This is done by using a known regression range for a specific test case.
    The old commit should show the error when its fuzzers run and the new one
    should not.
    """
    project_name = 'yara'
    old_commit = 'f79be4f2330f4b89ea2f42e1c44ca998c59a0c0f'
    new_commit = 'f50a39051ea8c7f10d6d8db9656658b49601caef'
    fuzzer = 'rules_fuzzer'
    test_data = 'infra/yara_test_data'
    build_fuzzer_from_commit(
        project_name,
        old_commit,
        '/usr/local/google/home/lneat/Documents/oss-fuzz/infra/tmp',
        sanitizer='address')
    old_error_code = self.reproduce_error(project_name, test_data, fuzzer)
    build_fuzzer_from_commit(
        project_name,
        new_commit,
        '/usr/local/google/home/lneat/Documents/oss-fuzz/infra/tmp',
        sanitizer='address')
    new_error_code = self.reproduce_error(project_name, test_data, fuzzer)
    self.assertNotEqual(new_error_code, old_error_code)
Beispiel #2
0
def bisect(commit_old, commit_new, testcase, fuzz_target, build_data):
  """From a commit range, this function caluclates which introduced a
  specific error from a fuzz testcase.

  Args:
    commit_old: The oldest commit in the error regression range
    commit_new: The newest commit in the error regression range
    testcase: The file path of the test case that triggers the error
    fuzz_target: The name of the fuzzer to be tested
    build_data: a class holding all of the input parameters for bisection

  Returns:
    The commit SHA that introduced the error or None
  """
  local_store_path = tempfile.mkdtemp()
  repo_url = build_specified_commit.infer_main_repo(build_data.project_name,
                                                    local_store_path,
                                                    commit_old)
  bisect_repo_manager = repo_manager.RepoManager(repo_url, local_store_path)
  commit_list = bisect_repo_manager.get_commit_list(commit_old, commit_new)
  build_specified_commit.build_fuzzer_from_commit(
      build_data.project_name, commit_list[0], bisect_repo_manager.repo_dir,
      build_data.engine, build_data.sanitizer, build_data.architecture,
      bisect_repo_manager)
  error_code = helper.reproduce_impl(build_data.project_name, fuzz_target,
                                     False, [], [], testcase)
  old_idx = len(commit_list) - 1
  new_idx = 0
  if len(commit_list) == 1:
    if not error_code:
      return None
    return commit_list[0]

  while old_idx - new_idx != 1:
    curr_idx = (old_idx + new_idx) // 2
    build_specified_commit.build_fuzzer_from_commit(
        build_data.project_name, commit_list[curr_idx],
        bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer,
        build_data.architecture, bisect_repo_manager)
    error_exists = (
        helper.reproduce_impl(build_data.project_name, fuzz_target, False, [],
                              [], testcase) == error_code)
    if error_exists == error_code:
      new_idx = curr_idx
    else:
      old_idx = curr_idx
  return commit_list[new_idx]
Beispiel #3
0
  def test_build_fuzzers_from_commit(self):
    """Tests if the fuzzers can build at a proper commit.

    This is done by using a known regression range for a specific test case.
    The old commit should show the error when its fuzzers run and the new one
    should not.
    """
    project_name = 'yara'
    old_commit = 'f79be4f2330f4b89ea2f42e1c44ca998c59a0c0f'
    new_commit = 'f50a39051ea8c7f10d6d8db9656658b49601caef'
    fuzzer = 'rules_fuzzer'
    test_data = 'infra/yara_test_data'
    build_specified_commit.build_fuzzer_from_commit(
        project_name, old_commit, 'tmp', sanitizer='address')
    old_error_code = helper.reproduce_impl(project_name, fuzzer, False, [], [],
                                           test_data)
    build_specified_commit.build_fuzzer_from_commit(
        project_name, new_commit, 'tmp', sanitizer='address')
    new_error_code = helper.reproduce_impl(project_name, fuzzer, False, [], [],
                                           test_data)
    self.assertNotEqual(new_error_code, old_error_code)
Beispiel #4
0
def bisect(commit_old, commit_new, testcase, fuzz_target, build_data):
  """From a commit range, this function caluclates which introduced a
  specific error from a fuzz testcase.

  Args:
    commit_old: The oldest commit in the error regression range
    commit_new: The newest commit in the error regression range
    testcase: The file path of the test case that triggers the error
    fuzz_target: The name of the fuzzer to be tested
    build_data: a class holding all of the input parameters for bisection

  Returns:
    The commit SHA that introduced the error or None

  Raises:
    ValueError: when a repo url can't be determine from the project
  """
  with tempfile.TemporaryDirectory() as tmp_dir:
    repo_url, repo_name = build_specified_commit.detect_main_repo_from_docker(
        build_data.project_name, commit_old)
    if not repo_url or not repo_name:
      raise ValueError('Main git repo can not be determined.')
    bisect_repo_manager = repo_manager.RepoManager(
        repo_url, tmp_dir, repo_name=repo_name)
    commit_list = bisect_repo_manager.get_commit_list(commit_old, commit_new)
    old_idx = len(commit_list) - 1
    new_idx = 0
    build_specified_commit.build_fuzzer_from_commit(
        build_data.project_name, commit_list[new_idx],
        bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer,
        build_data.architecture, bisect_repo_manager)
    expected_error_code = helper.reproduce_impl(build_data.project_name,
                                                fuzz_target, False, [], [],
                                                testcase)

    # Check if the error is persistent through the commit range
    build_specified_commit.build_fuzzer_from_commit(
        build_data.project_name, commit_list[old_idx],
        bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer,
        build_data.architecture, bisect_repo_manager)
    oldest_error_code = helper.reproduce_impl(build_data.project_name,
                                              fuzz_target, False, [], [],
                                              testcase)

    if expected_error_code == oldest_error_code:
      return commit_list[old_idx]

    while old_idx - new_idx > 1:
      curr_idx = (old_idx + new_idx) // 2
      build_specified_commit.build_fuzzer_from_commit(
          build_data.project_name, commit_list[curr_idx],
          bisect_repo_manager.repo_dir, build_data.engine, build_data.sanitizer,
          build_data.architecture, bisect_repo_manager)
      error_code = helper.reproduce_impl(build_data.project_name, fuzz_target,
                                         False, [], [], testcase)
      if expected_error_code == error_code:
        new_idx = curr_idx
      else:
        old_idx = curr_idx
    return commit_list[new_idx]