def process_crashes(self, cycle):
        """Process and store crashes."""
        benchmark_type = benchmark_config.get_config(
            self.benchmark).get('type')
        is_bug_benchmark = benchmark_type == 'bug'
        if not is_bug_benchmark:
            return []

        if not os.listdir(self.crashes_dir):
            logs.info('No crashes found for cycle %d.', cycle)
            return []

        logs.info('Saving crash files crashes for cycle %d.', cycle)
        self.save_crash_files(cycle)

        logs.info('Processing crashes for cycle %d.', cycle)
        app_binary = coverage_utils.get_coverage_binary(self.benchmark)
        crash_metadata = run_crashes.do_crashes_run(app_binary,
                                                    self.crashes_dir)
        crashes = []
        for crash_key in crash_metadata:
            crash = crash_metadata[crash_key]
            crashes.append(
                models.Crash(crash_key=crash_key,
                             crash_testcase=crash.crash_testcase,
                             crash_type=crash.crash_type,
                             crash_address=crash.crash_address,
                             crash_state=crash.crash_state,
                             crash_stacktrace=crash.crash_stacktrace))
        return crashes
Example #2
0
    def type(self):
        """Returns the type of the benchmark, which can be 'code' or 'bug',
        depending whether its for measuring code coverage only, or bug coverage
        as well.

        Raises ValueError in case of invalid benchmark type in the config.
        """
        try:
            benchmark_type = benchmark_config.get_config(self.name).get('type')
        except Exception:  # pylint: disable=broad-except
            return 'code'
        if not benchmark_type:
            return 'code'
        if benchmark_type not in ['code', 'bug']:
            raise ValueError('Invalid benchmark type: ' + benchmark_type)
        return benchmark_type
Example #3
0
def get_fuzzer_benchmark_pairs(fuzzers, benchmarks):
    """Return a tuple of (fuzzer, benchmark) pairs to build. Excludes
    unsupported fuzzers from each benchmark.
    """
    fuzzer_benchmark_pairs = list(itertools.product(fuzzers, benchmarks))

    unsupported_fuzzer_benchmark_pairs = []
    for benchmark in benchmarks:
        config = benchmark_config.get_config(benchmark)
        unsupported_fuzzers = config.get('unsupported_fuzzers')
        if not unsupported_fuzzers:
            continue
        unsupported_fuzzer_benchmark_pairs += list(
            itertools.product(unsupported_fuzzers, [benchmark]))

    return [
        i for i in fuzzer_benchmark_pairs
        if i not in unsupported_fuzzer_benchmark_pairs
    ]
Example #4
0
def is_oss_fuzz_benchmark(benchmark):
    """Returns if benchmark is a OSS-Fuzz benchmark."""
    return bool(benchmark_config.get_config(benchmark).get('commit_date'))
Example #5
0
def get_type(benchmark):
    """Returns the type of |benchmark|"""
    return benchmark_config.get_config(benchmark).get('type',
                                                      BenchmarkType.CODE.value)
Example #6
0
def get_project(benchmark):
    """Returns the project of |benchmark|"""
    return benchmark_config.get_config(benchmark)['project']
Example #7
0
def get_fuzz_target(benchmark):
    """Returns the fuzz target of |benchmark|"""
    return benchmark_config.get_config(benchmark)['fuzz_target']
def test_get_config(oss_fuzz_benchmark):
    """Test that we can get the configuration of a benchmark."""
    assert benchmark_config.get_config(conftest.OSS_FUZZ_BENCHMARK_NAME) == (
        conftest.OSS_FUZZ_BENCHMARK_CONFIG)
Example #9
0
 def type(self):
     """Type of benchmark."""
     return benchmark_config.get_config(self.name).get('type')
Example #10
0
def run_fuzzer(max_total_time, log_filename):
    """Runs the fuzzer using its script. Logs stdout and stderr of the fuzzer
    script to |log_filename| if provided."""
    input_corpus = environment.get('SEED_CORPUS_DIR')
    output_corpus = environment.get('OUTPUT_CORPUS_DIR')
    fuzz_target_name = environment.get('FUZZ_TARGET')
    target_binary = fuzzer_utils.get_fuzz_target_binary(FUZZ_TARGET_DIR,
                                                        fuzz_target_name)
    if not target_binary:
        logs.error('Fuzz target binary not found.')
        return

    _unpack_clusterfuzz_seed_corpus(target_binary, input_corpus)
    _clean_seed_corpus(input_corpus)

    if max_total_time is None:
        logs.warning('max_total_time is None. Fuzzing indefinitely.')

    runner_niceness = environment.get('RUNNER_NICENESS', 0)

    # Set sanitizer options environment variables if this is a bug based
    # benchmark.
    env = None
    benchmark = environment.get('BENCHMARK')
    if benchmark_config.get_config(benchmark).get('type') == 'bug':
        env = os.environ.copy()
        sanitizer.set_sanitizer_options(env, is_fuzz_run=True)

    try:
        # Because the runner is launched at a higher priority,
        # set it back to the default(0) for fuzzing processes.
        command = [
            'nice', '-n',
            str(0 - runner_niceness), 'python3', '-u', '-c',
            ('from fuzzers.{fuzzer} import fuzzer; '
             'fuzzer.fuzz('
             "'{input_corpus}', '{output_corpus}', '{target_binary}')").format(
                 fuzzer=environment.get('FUZZER'),
                 input_corpus=shlex.quote(input_corpus),
                 output_corpus=shlex.quote(output_corpus),
                 target_binary=shlex.quote(target_binary))
        ]

        # Write output to stdout if user is fuzzing from command line.
        # Otherwise, write output to the log file.
        if environment.get('FUZZ_OUTSIDE_EXPERIMENT'):
            new_process.execute(command,
                                timeout=max_total_time,
                                write_to_stdout=True,
                                kill_children=True,
                                env=env)
        else:
            with open(log_filename, 'wb') as log_file:
                new_process.execute(command,
                                    timeout=max_total_time,
                                    output_file=log_file,
                                    kill_children=True,
                                    env=env)
    except subprocess.CalledProcessError:
        global fuzzer_errored_out  # pylint:disable=invalid-name
        fuzzer_errored_out = True
        logs.error('Fuzz process returned nonzero.')
Example #11
0
def get_project(benchmark):
    """Returns the OSS-Fuzz project of |benchmark| if it is based on an
    OSS-Fuzz project, otherwise raises ValueError."""
    return benchmark_config.get_config(benchmark)['project']