Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/test/fuzz/fuzz_runner.h
Line
Count
Source
1
#pragma once
2
3
#include <cstdint>
4
#include <cwchar>
5
6
// Bring in DEFINE_PROTO_FUZZER definition as per
7
// https://github.com/google/libprotobuf-mutator#integrating-with-libfuzzer.
8
#include "libprotobuf_mutator/src/libfuzzer/libfuzzer_macro.h"
9
// Bring in FuzzedDataProvider, see
10
// https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider
11
#include "fuzzer/FuzzedDataProvider.h"
12
#include "spdlog/spdlog.h"
13
14
namespace Envoy {
15
namespace Fuzz {
16
17
// Each test may need a sub-environment of that provided by //test/test_common:environment_lib,
18
// since each fuzz invocation runs in the same process, but might want a distinct tmp sandbox for
19
// example.
20
class PerTestEnvironment {
21
public:
22
  PerTestEnvironment();
23
  ~PerTestEnvironment();
24
25
2.84k
  std::string temporaryPath(const std::string& path) const { return test_tmpdir_ + "/" + path; }
26
3.09k
  const std::string& testId() const { return test_id_; }
27
28
private:
29
  static uint32_t test_num_;
30
  const uint32_t per_test_num_;
31
  const std::string test_tmpdir_;
32
  const std::string test_id_;
33
};
34
35
class Runner {
36
public:
37
  /**
38
   * Setup the environment for fuzz testing. Multiple execute() runs may be
39
   * invoked in this environment.
40
   * @param argc number of command-line args.
41
   * @param argv array of command-line args.
42
   * @param default_loglevel default log level (overridable with -l).
43
   */
44
  static void setupEnvironment(int argc, char** argv, spdlog::level::level_enum default_log_level);
45
46
  /**
47
   * @return spdlog::level::level_enum the log level for the fuzzer.
48
   */
49
9.52k
  static spdlog::level::level_enum logLevel() { return log_level_; }
50
51
private:
52
  static spdlog::level::level_enum log_level_;
53
};
54
55
/**
56
 * Establishes a function to run before the test process exits. This enables
57
 * threads, mocks, and other objects that are expensive to create to be shared
58
 * between test methods.
59
 */
60
void addCleanupHook(std::function<void()>);
61
62
/**
63
 * Runs all cleanup hooks.
64
 */
65
void runCleanupHooks();
66
67
} // namespace Fuzz
68
} // namespace Envoy
69
70
// Fuzz test startup hook, see
71
// https://llvm.org/docs/LibFuzzer.html#startup-initialization.
72
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv);
73
74
// See https://llvm.org/docs/LibFuzzer.html#fuzz-target.
75
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
76
77
#ifdef PERSISTENT_FUZZER
78
8
template <typename T> T& initFuzzVar(T* ptr) {
79
8
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
initFuzzVar<Envoy::H1FuzzIntegrationTest>(Envoy::H1FuzzIntegrationTest*)::{lambda()#1}::operator()() const
Line
Count
Source
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
h1_fuzz.cc:initFuzzVar<Envoy::H1FuzzIntegrationTest::replay(test::integration::CaptureFuzzTestCase const&, bool)::Init>(Envoy::H1FuzzIntegrationTest::replay(test::integration::CaptureFuzzTestCase const&, bool)::Init*)::{lambda()#1}::operator()() const
Line
Count
Source
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
initFuzzVar<Envoy::H2FuzzIntegrationTest>(Envoy::H2FuzzIntegrationTest*)::{lambda()#1}::operator()() const
Line
Count
Source
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
h2_fuzz.cc:initFuzzVar<Envoy::H2FuzzIntegrationTest::replay(test::integration::H2CaptureFuzzTestCase const&, bool)::Init>(Envoy::H2FuzzIntegrationTest::replay(test::integration::H2CaptureFuzzTestCase const&, bool)::Init*)::{lambda()#1}::operator()() const
Line
Count
Source
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
80
8
  return *ptr;
81
8
}
Envoy::H1FuzzIntegrationTest& initFuzzVar<Envoy::H1FuzzIntegrationTest>(Envoy::H1FuzzIntegrationTest*)
Line
Count
Source
78
2
template <typename T> T& initFuzzVar(T* ptr) {
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
80
2
  return *ptr;
81
2
}
h1_fuzz.cc:Envoy::H1FuzzIntegrationTest::replay(test::integration::CaptureFuzzTestCase const&, bool)::Init& initFuzzVar<Envoy::H1FuzzIntegrationTest::replay(test::integration::CaptureFuzzTestCase const&, bool)::Init>(Envoy::H1FuzzIntegrationTest::replay(test::integration::CaptureFuzzTestCase const&, bool)::Init*)
Line
Count
Source
78
2
template <typename T> T& initFuzzVar(T* ptr) {
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
80
2
  return *ptr;
81
2
}
Envoy::H2FuzzIntegrationTest& initFuzzVar<Envoy::H2FuzzIntegrationTest>(Envoy::H2FuzzIntegrationTest*)
Line
Count
Source
78
2
template <typename T> T& initFuzzVar(T* ptr) {
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
80
2
  return *ptr;
81
2
}
h2_fuzz.cc:Envoy::H2FuzzIntegrationTest::replay(test::integration::H2CaptureFuzzTestCase const&, bool)::Init& initFuzzVar<Envoy::H2FuzzIntegrationTest::replay(test::integration::H2CaptureFuzzTestCase const&, bool)::Init>(Envoy::H2FuzzIntegrationTest::replay(test::integration::H2CaptureFuzzTestCase const&, bool)::Init*)
Line
Count
Source
78
2
template <typename T> T& initFuzzVar(T* ptr) {
79
2
  Envoy::Fuzz::addCleanupHook([ptr]() { delete ptr; });
80
2
  return *ptr;
81
2
}
82
5.04k
#define PERSISTENT_FUZZ_VAR(type, var, args) static type& var = initFuzzVar(new type(args))
83
#else
84
#define PERSISTENT_FUZZ_VAR(type, var, args) type var args
85
#endif
86
87
#define DEFINE_TEST_ONE_INPUT_IMPL                                                                 \
88
32.6k
  extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {                        \
89
32.6k
    EnvoyTestOneInput(data, size);                                                                 \
90
32.6k
    return 0;                                                                                      \
91
32.6k
  }
92
93
/**
94
 * Define a fuzz test. This should be used to define a fuzz_cc_fuzz_test_target with:
95
 *
96
 * DEFINE_FUZZER(const uint8_t* buf, size_t len) {
97
 *   // Do some test stuff with buf/len.
98
 *   return 0;
99
 * }
100
 */
101
#define DEFINE_FUZZER                                                                              \
102
  static void EnvoyTestOneInput(const uint8_t* buf, size_t len);                                   \
103
  DEFINE_TEST_ONE_INPUT_IMPL                                                                       \
104
  static void EnvoyTestOneInput