示例#1
0
    def _merge_new_units(self, target_path, corpus_dir, new_corpus_dir,
                         fuzz_corpus_dirs, arguments, stat_overrides):
        """Merge new units."""
        # Make a decision on whether merge step is needed at all. If there are no
        # new units added by libFuzzer run, then no need to do merge at all.
        new_units_added = shell.get_directory_file_count(new_corpus_dir)
        if not new_units_added:
            stat_overrides['new_units_added'] = 0
            logs.log(
                'Skipped corpus merge since no new units added by fuzzing.')
            return

        # If this times out, it's possible that we will miss some units. However, if
        # we're taking >10 minutes to load/merge the corpus something is going very
        # wrong and we probably don't want to make things worse by adding units
        # anyway.
        merge_corpus = self._create_merge_corpus_dir()

        merge_dirs = [new_corpus_dir]
        merge_dirs.extend(fuzz_corpus_dirs)

        # Merge the new units with the initial corpus.
        if corpus_dir not in merge_dirs:
            merge_dirs.append(corpus_dir)

        old_corpus_len = shell.get_directory_file_count(corpus_dir)

        new_units_added = 0
        try:
            result = self.minimize_corpus(
                target_path=target_path,
                arguments=arguments,
                input_dirs=merge_dirs,
                output_dir=merge_corpus,
                reproducers_dir=None,
                max_time=engine_common.get_merge_timeout(
                    libfuzzer.DEFAULT_MERGE_TIMEOUT))

            libfuzzer.move_mergeable_units(merge_corpus, corpus_dir)
            new_corpus_len = shell.get_directory_file_count(corpus_dir)
            new_units_added = new_corpus_len - old_corpus_len

            if result.logs:
                stat_overrides.update(
                    stats.parse_stats_from_merge_log(result.logs.splitlines()))
        except MergeError:
            logs.log_warn('Merge failed', target=os.path.basename(target_path))

        stat_overrides['new_units_added'] = new_units_added

        logs.log('Stats calculated', stats=stat_overrides)

        # Record the stats to make them easily searchable in stackdriver.
        if new_units_added:
            logs.log('New units added to corpus: %d.' % new_units_added)
        else:
            logs.log('No new units found.')
示例#2
0
 def move_mergeable_units(self):
     """Helper function for move_mergeable_units."""
     libfuzzer.move_mergeable_units(self.MERGE_DIRECTORY,
                                    self.CORPUS_DIRECTORY)
示例#3
0
    def _merge_new_units(
        self,
        target_path,
        corpus_dir,
        new_corpus_dir,
        fuzz_corpus_dirs,
        arguments,
        stat_overrides,
    ):
        """Merge new units."""
        # Make a decision on whether merge step is needed at all. If there are no
        # new units added by libFuzzer run, then no need to do merge at all.
        new_units_added = shell.get_directory_file_count(new_corpus_dir)
        if not new_units_added:
            stat_overrides["new_units_added"] = 0
            logs.log(
                "Skipped corpus merge since no new units added by fuzzing.")
            return

        # If this times out, it's possible that we will miss some units. However, if
        # we're taking >10 minutes to load/merge the corpus something is going very
        # wrong and we probably don't want to make things worse by adding units
        # anyway.
        merge_corpus = self._create_merge_corpus_dir()

        merge_dirs = fuzz_corpus_dirs[:]

        # Merge the new units with the initial corpus.
        if corpus_dir not in merge_dirs:
            merge_dirs.append(corpus_dir)

        old_corpus_len = shell.get_directory_file_count(corpus_dir)

        new_units_added = 0
        try:
            result = self._minimize_corpus_two_step(
                target_path=target_path,
                arguments=arguments,
                existing_corpus_dirs=merge_dirs,
                new_corpus_dir=new_corpus_dir,
                output_corpus_dir=merge_corpus,
                reproducers_dir=None,
                max_time=engine_common.get_merge_timeout(
                    libfuzzer.DEFAULT_MERGE_TIMEOUT),
            )

            libfuzzer.move_mergeable_units(merge_corpus, corpus_dir)
            new_corpus_len = shell.get_directory_file_count(corpus_dir)
            new_units_added = new_corpus_len - old_corpus_len

            stat_overrides.update(result.stats)
        except (MergeError, engine.TimeoutError) as e:
            logs.log_warn("Merge failed.", error=e.message)

        stat_overrides["new_units_added"] = new_units_added

        # Record the stats to make them easily searchable in stackdriver.
        logs.log("Stats calculated.", stats=stat_overrides)
        if new_units_added:
            logs.log("New units added to corpus: %d." % new_units_added)
        else:
            logs.log("No new units found.")