Beispiel #1
0
def find_fuzzer_path(build_directory, fuzzer_name):
    """Find the fuzzer path with the given name."""
    if not build_directory:
        # Grey-box fuzzers might not have the build directory for a particular job
        # configuration when doing variant task testing (e.g. Android on-device
        # fuzz target might not exist on host). In this case, treat it similar to
        # target not found by returning None.
        logs.log_warn('No build directory found for fuzzer: %s' % fuzzer_name)
        return None

    if environment.platform() == 'FUCHSIA':
        # Fuchsia targets are not on disk.
        return fuzzer_name

    # TODO(ochang): This is necessary for legacy testcases, which include the
    # project prefix in arguments. Remove this in the near future.
    project_name = environment.get_value('PROJECT_NAME')
    legacy_name_prefix = u''
    if project_name:
        legacy_name_prefix = project_name + u'_'

    fuzzer_filename = environment.get_executable_filename(fuzzer_name)
    for root, _, files in shell.walk(build_directory):
        for filename in files:
            if (legacy_name_prefix.encode() + filename == fuzzer_name
                    or filename == fuzzer_filename):
                return os.path.join(root, filename)

    # This is an expected case when doing regression testing with old builds
    # that do not have that fuzz target. It can also happen when a host sends a
    # message to an untrusted worker that just restarted and lost information on
    # build directory.
    logs.log_warn('Fuzzer: %s not found in build_directory: %s.' %
                  (fuzzer_name, build_directory))
    return None
def remove_testcases_from_directories(directories):
    """Removes all testcases and their dependencies from testcase directories."""
    generators = []
    for directory in directories:
        if not directory.strip():
            continue

        # If there is a bot-specific files list, delete it now.
        bot_testcases_file_path = utils.get_bot_testcases_file_path(directory)
        shell.remove_file(bot_testcases_file_path)

        generators.append(shell.walk(directory))

    for generator in generators:
        for structure in generator:
            base_directory = structure[0]
            for filename in structure[2]:
                if not is_testcase_resource(filename):
                    continue

                if filename.startswith(RESOURCES_PREFIX):
                    # In addition to removing this file, remove all resources.
                    resources_file_path = os.path.join(base_directory,
                                                       filename)
                    resources = read_resource_list(resources_file_path)
                    for resource in resources:
                        shell.remove_file(resource)

                file_path = os.path.join(base_directory, filename)
                shell.remove_file(file_path)
def get_testcases_from_directories(directories):
    """Returns all testcases from testcase directories."""
    testcase_paths = []
    max_testcases = environment.get_value('MAX_TESTCASES')

    generators = []
    for directory in directories:
        if not directory.strip():
            continue

        generators.append(shell.walk(directory))

    for generator in generators:
        for structure in generator:
            base_directory = structure[0]
            for filename in structure[2]:
                if not filename.startswith(FUZZ_PREFIX):
                    continue

                if filename.endswith(COVERAGE_SUFFIX):
                    continue

                file_path = os.path.join(base_directory, filename)
                if not os.path.getsize(file_path):
                    continue

                testcase_paths.append(utils.normalize_path(file_path))
                if len(testcase_paths) == max_testcases:
                    return testcase_paths

    return testcase_paths
def get_resource_dependencies(testcase_absolute_path, test_prefix=FUZZ_PREFIX):
    """Returns the list of testcase resource dependencies."""
    resources = []
    if not os.path.exists(testcase_absolute_path):
        return resources

    base_directory = os.path.dirname(testcase_absolute_path)
    testcase_filename = os.path.basename(testcase_absolute_path)

    # FIXME(mbarbella): Remove this when all fuzzers are using "resources-".
    # This code includes the dependencies that begin with
    # dependency prefix and are referenced in the testcase.
    testcase_contents = None
    for filename in os.listdir(base_directory):
        if filename.startswith(DEPENDENCY_PREFIX):
            # Only load the testcase contents if necessary.
            if not testcase_contents:
                file_handle = open(testcase_absolute_path, 'rb')
                testcase_contents = file_handle.read()
                file_handle.close()

            if filename in testcase_contents:
                file_path = os.path.join(base_directory, filename)
                resources.append(file_path)

    # This code includes the dependencies in cases when the testcase itself is a
    # just a wrapper file around the actual testcase.
    if DEPENDENCY_PREFIX in testcase_absolute_path:
        dependency_filename = os.path.splitext(testcase_filename)[0]
        dependency_filename = re.compile(DEPENDENCY_PREFIX).sub(
            '', dependency_filename, 1)
        dependency_filename = re.compile(FUZZ_PREFIX).sub(
            '', dependency_filename, 1)
        dependency_filename = re.compile(HTTP_PREFIX).sub(
            '', dependency_filename, 1)
        dependency_file_path = os.path.join(base_directory,
                                            dependency_filename)
        resources.append(dependency_file_path)

    # Check to see if this test case lists all resources in a resources file.
    if testcase_filename.startswith(test_prefix):
        stripped_testcase_name = testcase_filename[len(test_prefix):]
        resources_filename = '%s%s' % (RESOURCES_PREFIX,
                                       stripped_testcase_name)
        resources_file_path = os.path.join(base_directory, resources_filename)
        resources += read_resource_list(resources_file_path)

    # For extensions, archive everything in the extension directory.
    if APPS_PREFIX in testcase_filename or EXTENSIONS_PREFIX in testcase_filename:
        for root, _, files in shell.walk(base_directory):
            for filename in files:
                file_path = os.path.join(root, filename)
                if file_path == testcase_absolute_path:
                    continue

                resources.append(file_path)

    return resources
Beispiel #5
0
def clear_old_files(directory, extracted_file_set):
  """Remove files from the directory that isn't in the given file list."""
  for root_directory, _, filenames in shell.walk(directory):
    for filename in filenames:
      file_path = os.path.join(root_directory, filename)
      if file_path not in extracted_file_set:
        shell.remove_file(file_path)

  shell.remove_empty_directories(directory)
Beispiel #6
0
def clear_pyc_files(directory):
  """Recursively remove all .pyc files from the given directory"""
  for root_directory, _, filenames in shell.walk(directory):
    for filename in filenames:
      if not filename.endswith('.pyc'):
        continue

      file_path = os.path.join(root_directory, filename)
      shell.remove_file(file_path)
Beispiel #7
0
def get_fuzz_targets_local(path):
  """Get list of fuzz targets paths (local)."""
  fuzz_target_paths = []

  for root, _, files in shell.walk(path):
    for filename in files:
      file_path = os.path.join(root, filename)
      if is_fuzz_target_local(file_path):
        fuzz_target_paths.append(file_path)

  return fuzz_target_paths
Beispiel #8
0
def list_files(request, _):
    """List files."""
    file_paths = []
    if request.recursive:
        for root, _, files in shell.walk(request.path):
            for filename in files:
                file_paths.append(os.path.join(root, filename))
    else:
        file_paths.extend(
            os.path.join(request.path, path)
            for path in os.listdir(request.path))

    return untrusted_runner_pb2.ListFilesResponse(file_paths=file_paths)
Beispiel #9
0
def find_fuzzer_path(build_directory, fuzzer_name, is_blackbox=False):
    """Find the fuzzer path with the given name."""
    # Blackbox fuzzers are special cases. They run from the fuzzers directory
    # rather than using a target from the build archive.
    if is_blackbox:
        fuzzer_directory = environment.get_value('FUZZERS_DIR')
        fuzzer_directory = os.path.join(fuzzer_directory, fuzzer_name)
        fuzzer = data_types.Fuzzer.query(
            data_types.Fuzzer.name == fuzzer_name).get()
        return os.path.join(fuzzer_directory, fuzzer.executable_path)

    if not build_directory:
        # Grey-box fuzzers might not have the build directory for a particular job
        # configuration when doing variant task testing (e.g. Android on-device
        # fuzz target might not exist on host). In this case, treat it similar to
        # target not found by returning None.
        logs.log_warn('No build directory found for fuzzer: %s' % fuzzer_name)
        return None

    if environment.platform() == 'FUCHSIA':
        # Fuchsia targets are not on disk.
        return fuzzer_name

    if environment.platform() == 'ANDROID_KERNEL':
        return os.path.join(build_directory, 'syzkaller', 'bin', 'syz-manager')

    # TODO(ochang): This is necessary for legacy testcases, which include the
    # project prefix in arguments. Remove this in the near future.
    project_name = environment.get_value('PROJECT_NAME')
    legacy_name_prefix = u''
    if project_name:
        legacy_name_prefix = project_name + u'_'

    fuzzer_filename = environment.get_executable_filename(fuzzer_name)
    for root, _, files in shell.walk(build_directory):
        for filename in files:
            if (legacy_name_prefix + filename == fuzzer_name
                    or filename == fuzzer_filename):
                return os.path.join(root, filename)

    # This is an expected case when doing regression testing with old builds
    # that do not have that fuzz target. It can also happen when a host sends a
    # message to an untrusted worker that just restarted and lost information on
    # build directory.
    logs.log_warn('Fuzzer: %s not found in build_directory: %s.' %
                  (fuzzer_name, build_directory))
    return None
Beispiel #10
0
def copy_directory_to_worker(host_directory, worker_directory, replace=False):
    """Recursively copy a directory to the worker. Directories are created as
  needed. Unless |replace| is True, files already in |worker_path| will remain
  after this call."""
    if replace:
        remove_directory(worker_directory, recreate=True)

    for root, _, files in shell.walk(host_directory):
        for filename in files:
            file_path = os.path.join(root, filename)
            worker_file_path = os.path.join(
                worker_directory, os.path.relpath(file_path, host_directory))
            if not copy_file_to_worker(file_path, worker_file_path):
                logs.log_warn('Failed to copy %s to worker.' % file_path)
                return False

    return True
Beispiel #11
0
def create_testcase_list_file(output_directory):
  """Create a testcase list file for tests in a directory."""
  files_list = []
  files_list_file_path = os.path.join(output_directory, TESTCASE_LIST_FILENAME)
  for root, _, files in shell.walk(output_directory):
    for filename in files:
      if filename.endswith(INFO_FILE_EXTENSION):
        # Skip an info file.
        continue

      file_path = os.path.join(root, filename)
      if not utils.is_valid_testcase_file(file_path, check_if_exists=False):
        continue

      normalized_relative_file_path = utils.get_normalized_relative_path(
          file_path, output_directory)
      files_list.append(normalized_relative_file_path)

  utils.write_data_to_file('\n'.join(sorted(files_list)), files_list_file_path)
Beispiel #12
0
 def _list_files_recursive(self, fs_path):
   """List files recursively."""
   for root, _, filenames in shell.walk(fs_path):
     for filename in filenames:
       yield os.path.join(root, filename)