brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 5a79710 Raw
87 lines · cpp
1// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.2// See https://llvm.org/LICENSE.txt for license information.3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception4 5// This is a fuzz target for running out-of-process fuzzing for a6// binary specified via environment variable LIBFUZZER_OOP_TARGET.7// libFuzzer is not designed for out-of-process fuzzing and so this8// ad-hoc rig lacks many of the in-process libFuzzer features, and is slow,9// but it does provide the basic functionality, which is to run the target10// many times in parallel, feeding in the mutants, and expanding the corpus.11// Use this only for very slow targets (slower than ~ 10 exec/s)12// that you can't convert to conventional libFuzzer fuzz targets.13//14// The target binary (which could be a shell script, or anything),15// consumes one file as an input and produces the file with coverage counters16// as the output (output path is passed via SANCOV_OUT).17// One way to produce a valid binary target is to build it with18// -fsanitize-coverage=inline-8bit-counters and link it with SanCovDump.cpp,19// found in the same directory.20//21// Example usage:22/*23 clang -fsanitize=fuzzer OutOfProcessFuzzTarget.cpp -o oop-fuzz &&24 clang -c -fsanitize-coverage=inline-8bit-counters SimpleTest.cpp &&25 clang -c ../../lib/fuzzer/standalone/StandaloneFuzzTargetMain.c &&26 clang -c SanCovDump.cpp &&27 clang++ SanCovDump.o SimpleTest.o  StandaloneFuzzTargetMain.o -o oop-target &&28 rm -rf CORPUS && mkdir CORPUS && echo > CORPUS/seed &&29 LIBFUZZER_OOP_TARGET="./oop-target > /dev/null 2>&1 " ./oop-fuzz CORPUS -jobs=4230 31*/32#include <fcntl.h>33#include <stdint.h>34#include <stdio.h>35#include <sys/stat.h>36#include <sys/types.h>37#include <unistd.h>38 39#include <string>40 41// An arbitrary large number.42// If your target is so large that it has more than this number of coverage43// edges, you may want to increase this number to match your binary,44// otherwise part of the coverage will be lost.45// For small targets there is no reason to reduce this number.46static const size_t kCountersSize = 1 << 20;47 48__attribute__((section(49    "__libfuzzer_extra_counters"))) static uint8_t Counters[kCountersSize];50 51static std::string *Run, *IN, *COV;52 53void TearDown() {54  unlink(COV->c_str());55  unlink(IN->c_str());56}57 58bool Initialize() {59  IN = new std::string("lf-oop-in-" + std::to_string(getpid()));60  COV = new std::string("lf-oop-cov-" + std::to_string(getpid()));61  const char *TargetEnv = getenv("LIBFUZZER_OOP_TARGET");62  if (!TargetEnv) {63    fprintf(stderr, "Please define LIBFUZZER_OOP_TARGET\n");64    exit(1);65  }66  Run = new std::string("SANCOV_OUT=" + *COV + " " + TargetEnv + " " + *IN);67  fprintf(stderr, "libFuzzer: OOP command: %s\n", Run->c_str());68  atexit(TearDown);69  return true;70}71 72extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {73  static bool Inited = Initialize();74  if (size == 0)75    return 0;76  if (FILE *f = fopen(IN->c_str(), "w")) {77    fwrite(data, 1, size, f);78    fclose(f);79  }80  system(Run->c_str());81  if (FILE *f = fopen(COV->c_str(), "r")) {82    fread(Counters, 1, kCountersSize, f);83    fclose(f);84  }85  return 0;86}87