Ejemplo n.º 1
0
def get_corpus_directories(main_corpus_directory,
                           fuzzer_path,
                           fuzzing_strategies,
                           minijail_chroot=None):
  """Return a list of corpus directories to be passed to the fuzzer binary for
  fuzzing."""
  corpus_directories = []

  # Set up scratch directory for writing new units.
  new_testcases_directory = create_corpus_directory('new')

  corpus_directories.append(new_testcases_directory)

  # Check for seed corpus and add it into corpus directory.
  engine_common.unpack_seed_corpus_if_needed(fuzzer_path, main_corpus_directory)

  # Pick a few testcases from our corpus to use as the initial corpus.
  subset_size = engine_common.random_choice(
      engine_common.CORPUS_SUBSET_NUM_TESTCASES)

  if (engine_common.do_corpus_subset() and
      shell.get_directory_file_count(main_corpus_directory) > subset_size):
    # Copy |subset_size| testcases into 'subset' directory.
    corpus_subset_directory = create_corpus_directory('subset')
    copy_from_corpus(corpus_subset_directory, main_corpus_directory,
                     subset_size)
    corpus_directories.append(corpus_subset_directory)
    fuzzing_strategies.append(strategy.CORPUS_SUBSET_STRATEGY + '_' +
                              str(subset_size))
    if minijail_chroot:
      bind_corpus_dirs(minijail_chroot, [main_corpus_directory])
  else:
    # Regular fuzzing with the full main corpus directory.
    corpus_directories.append(main_corpus_directory)

  if minijail_chroot:
    bind_corpus_dirs(minijail_chroot, corpus_directories)

  return corpus_directories
Ejemplo n.º 2
0
def generate_new_testcase_mutations_using_radamsa(
        corpus_directory, new_testcase_mutations_directory,
        expected_completion_time):
    """Generate new testcase mutations based on Radamsa."""
    radamsa_path = get_radamsa_path()
    if not radamsa_path:
        # Mutations using radamsa are not supported on current platform, bail out.
        return

    radamsa_runner = new_process.ProcessRunner(radamsa_path)
    files_list = shell.get_files_list(corpus_directory)
    if not files_list:
        # No mutations to do on an empty corpus, bail out.
        return

    old_corpus_size = shell.get_directory_file_count(
        new_testcase_mutations_directory)

    for i in range(RADAMSA_MUTATIONS):
        original_file_path = engine_common.random_choice(files_list)
        original_filename = os.path.basename(original_file_path)
        output_path = os.path.join(
            new_testcase_mutations_directory,
            'radamsa-%08d-%s' % (i + 1, original_filename))

        result = radamsa_runner.run_and_wait(
            ['-o', output_path, original_file_path], timeout=RADAMSA_TIMEOUT)
        if result.return_code or result.timed_out:
            logs.log_error('Radamsa failed to mutate or timed out.',
                           output=result.output)

        # Check if we exceeded our timeout. If yes, do no more mutations and break.
        if time.time() > expected_completion_time:
            break

    new_corpus_size = shell.get_directory_file_count(
        new_testcase_mutations_directory)
    logs.log('Added %d tests using Radamsa mutations.' %
             (new_corpus_size - old_corpus_size))
Ejemplo n.º 3
0
    def prepare(self, corpus_dir, target_path, _):
        """Prepare for a fuzzing session, by generating options. Returns a
    FuzzOptions object.

    Args:
      corpus_dir: The main corpus directory.
      target_path: Path to the target.
      build_dir: Path to the build directory.

    Returns:
      A FuzzOptions object.
    """
        arguments = fuzzer.get_arguments(target_path)
        strategy_pool = strategy_selection.generate_weighted_strategy_pool(
            strategy_list=strategy.LIBFUZZER_STRATEGY_LIST,
            use_generator=True,
            engine_name=self.name)
        strategy_info = launcher.pick_strategies(strategy_pool, target_path,
                                                 corpus_dir, arguments)

        arguments.extend(strategy_info.arguments)

        # Check for seed corpus and add it into corpus directory.
        engine_common.unpack_seed_corpus_if_needed(target_path, corpus_dir)

        # Pick a few testcases from our corpus to use as the initial corpus.
        subset_size = engine_common.random_choice(
            engine_common.CORPUS_SUBSET_NUM_TESTCASES)

        if (not strategy_info.use_dataflow_tracing
                and strategy_pool.do_strategy(strategy.CORPUS_SUBSET_STRATEGY)
                and shell.get_directory_file_count(corpus_dir) > subset_size):
            # Copy |subset_size| testcases into 'subset' directory.
            corpus_subset_dir = self._create_temp_corpus_dir('subset')
            launcher.copy_from_corpus(corpus_subset_dir, corpus_dir,
                                      subset_size)
            strategy_info.fuzzing_strategies.append(
                strategy.CORPUS_SUBSET_STRATEGY.name + '_' + str(subset_size))
            strategy_info.additional_corpus_dirs.append(corpus_subset_dir)
        else:
            strategy_info.additional_corpus_dirs.append(corpus_dir)

        # Check dict argument to make sure that it's valid.
        dict_argument = fuzzer_utils.extract_argument(arguments,
                                                      constants.DICT_FLAG,
                                                      remove=False)
        if dict_argument and not os.path.exists(dict_argument):
            logs.log_error('Invalid dict %s for %s.' %
                           (dict_argument, target_path))
            fuzzer_utils.extract_argument(arguments, constants.DICT_FLAG)

        # If there's no dict argument, check for %target_binary_name%.dict file.
        if (not fuzzer_utils.extract_argument(
                arguments, constants.DICT_FLAG, remove=False)):
            default_dict_path = dictionary_manager.get_default_dictionary_path(
                target_path)
            if os.path.exists(default_dict_path):
                arguments.append(constants.DICT_FLAG + default_dict_path)

        return LibFuzzerOptions(corpus_dir, arguments,
                                strategy_info.fuzzing_strategies,
                                strategy_info.additional_corpus_dirs,
                                strategy_info.extra_env,
                                strategy_info.use_dataflow_tracing,
                                strategy_info.is_mutations_run)