Coverage Report

Created: 2021-02-21 07:20

/src/botan/src/fuzzer/fuzzers.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2015,2016,2017 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#ifndef BOTAN_FUZZER_DRIVER_H_
8
#define BOTAN_FUZZER_DRIVER_H_
9
10
#include <stdint.h>
11
#include <stdlib.h> // for setenv
12
#include <iostream>
13
#include <vector>
14
#include <botan/exceptn.h>
15
#include <botan/chacha_rng.h>
16
17
static const size_t max_fuzzer_input_size = 8192;
18
19
extern void fuzz(const uint8_t in[], size_t len);
20
21
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv);
22
extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len);
23
24
extern "C" int LLVMFuzzerInitialize(int *, char ***)
25
62
   {
26
   /*
27
   * This disables the mlock pool, as overwrites within the pool are
28
   * opaque to ASan or other instrumentation.
29
   */
30
62
   ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1);
31
62
   return 0;
32
62
   }
33
34
// Called by main() in libFuzzer or in main for AFL below
35
extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len)
36
47.1k
   {
37
47.1k
   if(len <= max_fuzzer_input_size)
38
46.9k
      {
39
46.9k
      fuzz(in, len);
40
46.9k
      }
41
47.1k
   return 0;
42
47.1k
   }
43
44
// Some helpers for the fuzzer jigs
45
46
inline Botan::RandomNumberGenerator& fuzzer_rng()
47
34.4k
   {
48
34.4k
   static Botan::ChaCha_RNG rng(Botan::secure_vector<uint8_t>(32));
49
34.4k
   return rng;
50
34.4k
   }
51
52
#define FUZZER_WRITE_AND_CRASH(expr) \
53
0
   do { std::cerr << expr; abort(); } while(0)
54
55
38.3k
#define FUZZER_ASSERT_EQUAL(x, y) do {                                  \
56
38.3k
   if(x != y) {                                                         \
57
0
      FUZZER_WRITE_AND_CRASH(#x << " = " << x << " !=\n"                \
58
0
                             << #y << " = " << y << "\n");              \
59
38.3k
   } } while(0)
60
61
#define FUZZER_ASSERT_TRUE(e)                                           \
62
104k
   do {                                                                 \
63
104k
   if(!(e)) {                                                           \
64
0
      FUZZER_WRITE_AND_CRASH("Expression " << #e << " was false");      \
65
104k
   } } while(0)
66
67
#if defined(BOTAN_FUZZER_IS_AFL) || defined(BOTAN_FUZZER_IS_TEST)
68
69
/* Stub for AFL */
70
71
#if defined(BOTAN_FUZZER_IS_AFL) && !defined(__AFL_COMPILER)
72
   #error "Build configured for AFL but not being compiled by AFL compiler"
73
#endif
74
75
#if defined(BOTAN_FUZZER_IS_TEST)
76
77
#include <fstream>
78
79
namespace {
80
81
int fuzz_files(char* files[])
82
   {
83
   for(size_t i = 0; files[i]; ++i)
84
      {
85
      std::ifstream in(files[i]);
86
87
      if(in.good())
88
         {
89
         std::vector<uint8_t> buf(max_fuzzer_input_size);
90
         in.read(reinterpret_cast<char*>(buf.data()), buf.size());
91
         const size_t got = in.gcount();
92
         buf.resize(got);
93
         buf.shrink_to_fit();
94
95
         LLVMFuzzerTestOneInput(buf.data(), got);
96
         }
97
      }
98
99
   return 0;
100
   }
101
102
}
103
104
#endif
105
106
int main(int argc, char* argv[])
107
   {
108
   LLVMFuzzerInitialize(&argc, &argv);
109
110
#if defined(BOTAN_FUZZER_IS_TEST)
111
   if(argc > 1)
112
      {
113
      return fuzz_files(&argv[1]);
114
      }
115
#endif
116
117
#if defined(__AFL_LOOP)
118
   while(__AFL_LOOP(1000))
119
#endif
120
      {
121
      std::vector<uint8_t> buf(max_fuzzer_input_size);
122
      std::cin.read(reinterpret_cast<char*>(buf.data()), buf.size());
123
      const size_t got = std::cin.gcount();
124
125
      buf.resize(got);
126
      buf.shrink_to_fit();
127
128
      LLVMFuzzerTestOneInput(buf.data(), got);
129
      }
130
   }
131
132
#elif defined(BOTAN_FUZZER_IS_KLEE)
133
134
#include <klee/klee.h>
135
136
int main(int argc, char* argv[])
137
   {
138
   LLVMFuzzerInitialize(&argc, &argv);
139
140
   uint8_t input[max_fuzzer_input_size] = { 0 };
141
   klee_make_symbolic(&input, sizeof(input), "input");
142
143
   size_t input_len = klee_range(0, sizeof(input), "input_len");
144
145
   LLVMFuzzerTestOneInput(input, input_len);
146
   }
147
148
#endif
149
150
#endif