forked from google/honggfuzz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
honggfuzz.h
385 lines (348 loc) · 11 KB
/
honggfuzz.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/*
*
* honggfuzz - core structures and macros
* -----------------------------------------
*
* Author: Robert Swiecki <[email protected]>
*
* Copyright 2010-2018 by Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
*/
#ifndef _HF_HONGGFUZZ_H_
#define _HF_HONGGFUZZ_H_
#include <dirent.h>
#include <inttypes.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <time.h>
#include "libhfcommon/util.h"
#define PROG_NAME "honggfuzz"
#define PROG_VERSION "2.3"
/* Name of the template which will be replaced with the proper name of the file */
#define _HF_FILE_PLACEHOLDER "___FILE___"
/* Default name of the report created with some architectures */
#define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
/* Default stack-size of created threads. */
#define _HF_PTHREAD_STACKSIZE (1024ULL * 1024ULL * 2ULL) /* 2MB */
/* Name of envvar which indicates sequential number of fuzzer */
#define _HF_THREAD_NO_ENV "HFUZZ_THREAD_NO"
/* Name of envvar which indicates that the netDriver should be used */
#define _HF_THREAD_NETDRIVER_ENV "HFUZZ_USE_NETDRIVER"
/* Name of envvar which indicates honggfuzz's log level in use */
#define _HF_LOG_LEVEL_ENV "HFUZZ_LOG_LEVEL"
/* Number of crash verifier iterations before tag crash as stable */
#define _HF_VERIFIER_ITER 5
/* Size (in bytes) for report data to be stored in stack before written to file */
#define _HF_REPORT_SIZE 32768
/* Perf bitmap size */
#define _HF_PERF_BITMAP_SIZE_16M (1024U * 1024U * 16U)
#define _HF_PERF_BITMAP_BITSZ_MASK 0x7FFFFFFULL
/* Maximum number of PC guards (=trace-pc-guard) we support */
#define _HF_PC_GUARD_MAX (1024ULL * 1024ULL * 64ULL)
/* Maximum size of the input file in bytes (1 MiB) */
#define _HF_INPUT_MAX_SIZE (1024ULL * 1024ULL)
/* Default maximum size of produced inputs */
#define _HF_INPUT_DEFAULT_SIZE (1024ULL * 8)
/* Per-thread bitmap */
#define _HF_PERTHREAD_BITMAP_FD 1018
/* FD used to report back used int/str constants from the fuzzed process */
#define _HF_CMP_BITMAP_FD 1019
/* FD used to log inside the child process */
#define _HF_LOG_FD 1020
/* FD used to represent the input file */
#define _HF_INPUT_FD 1021
/* FD used to pass coverage feedback from the fuzzed process */
#define _HF_COV_BITMAP_FD 1022
#define _HF_BITMAP_FD _HF_COV_BITMAP_FD /* Old name for _HF_COV_BITMAP_FD */
/* FD used to pass data to a persistent process */
#define _HF_PERSISTENT_FD 1023
/* Input file as a string */
#define _HF_INPUT_FILE_PATH "/dev/fd/" HF_XSTR(_HF_INPUT_FD)
/* Maximum number of supported execve() args */
#define _HF_ARGS_MAX 2048
/* Message indicating that the fuzzed process is ready for new data */
static const uint8_t HFReadyTag = 'R';
/* Maximum number of active fuzzing threads */
#define _HF_THREAD_MAX 1024U
/* Persistent-binary signature - if found within file, it means it's a persistent mode binary */
#define _HF_PERSISTENT_SIG "\x01_LIBHFUZZ_PERSISTENT_BINARY_SIGNATURE_\x02\xFF"
/* HF NetDriver signature - if found within file, it means it's a NetDriver-based binary */
#define _HF_NETDRIVER_SIG "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF"
/* printf() nonmonetary separator. According to MacOSX's man it's supported there as well */
#define _HF_NONMON_SEP "'"
typedef enum {
_HF_DYNFILE_NONE = 0x0,
_HF_DYNFILE_INSTR_COUNT = 0x1,
_HF_DYNFILE_BRANCH_COUNT = 0x2,
_HF_DYNFILE_BTS_EDGE = 0x10,
_HF_DYNFILE_IPT_BLOCK = 0x20,
_HF_DYNFILE_SOFT = 0x40,
} dynFileMethod_t;
typedef struct {
uint64_t cpuInstrCnt;
uint64_t cpuBranchCnt;
uint64_t bbCnt;
uint64_t newBBCnt;
uint64_t softCntPc;
uint64_t softCntEdge;
uint64_t softCntCmp;
} hwcnt_t;
typedef enum {
_HF_STATE_UNSET = 0,
_HF_STATE_STATIC,
_HF_STATE_DYNAMIC_DRY_RUN,
_HF_STATE_DYNAMIC_MAIN,
_HF_STATE_DYNAMIC_MINIMIZE,
} fuzzState_t;
typedef enum {
HF_MAYBE = -1,
HF_NO = 0,
HF_YES = 1,
} tristate_t;
struct _dynfile_t {
size_t size;
uint64_t cov[4];
size_t idx;
int fd;
uint64_t timeExecUSecs;
char path[PATH_MAX];
struct _dynfile_t* src;
uint32_t refs;
uint8_t* data;
TAILQ_ENTRY(_dynfile_t) pointers;
};
typedef struct _dynfile_t dynfile_t;
struct strings_t {
size_t len;
TAILQ_ENTRY(strings_t) pointers;
char s[];
};
typedef struct {
uint8_t pcGuardMap[_HF_PC_GUARD_MAX];
uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M];
uint32_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M];
uint64_t pidNewPC[_HF_THREAD_MAX];
uint64_t pidNewEdge[_HF_THREAD_MAX];
uint64_t pidNewCmp[_HF_THREAD_MAX];
uint64_t guardNb;
uint64_t pidTotalPC[_HF_THREAD_MAX];
uint64_t pidTotalEdge[_HF_THREAD_MAX];
uint64_t pidTotalCmp[_HF_THREAD_MAX];
} feedback_t;
typedef struct {
uint32_t cnt;
struct {
uint8_t val[32];
uint32_t len;
} valArr[1024 * 16];
} cmpfeedback_t;
typedef struct {
struct {
size_t threadsMax;
size_t threadsFinished;
uint32_t threadsActiveCnt;
pthread_t mainThread;
pid_t mainPid;
pthread_t threads[_HF_THREAD_MAX];
} threads;
struct {
const char* inputDir;
const char* outputDir;
DIR* inputDirPtr;
size_t fileCnt;
size_t testedFileCnt;
const char* fileExtn;
size_t maxFileSz;
size_t newUnitsAdded;
char workDir[PATH_MAX];
const char* crashDir;
const char* covDirNew;
bool saveUnique;
size_t dynfileqMaxSz;
size_t dynfileqCnt;
dynfile_t* dynfileqCurrent;
dynfile_t* dynfileq2Current;
TAILQ_HEAD(dyns_t, _dynfile_t) dynfileq;
bool exportFeedback;
} io;
struct {
int argc;
const char* const* cmdline;
bool nullifyStdio;
bool fuzzStdin;
const char* externalCommand;
const char* postExternalCommand;
const char* feedbackMutateCommand;
bool netDriver;
bool persistent;
uint64_t asLimit;
uint64_t rssLimit;
uint64_t dataLimit;
uint64_t coreLimit;
uint64_t stackLimit;
bool clearEnv;
char* env_ptrs[128];
char env_vals[128][4096];
sigset_t waitSigSet;
} exe;
struct {
time_t timeStart;
time_t runEndTime;
time_t tmOut;
time_t lastCovUpdate;
int64_t timeOfLongestUnitUSecs;
bool tmoutVTALRM;
} timing;
struct {
struct {
uint8_t val[256];
size_t len;
} dictionary[1024];
size_t dictionaryCnt;
const char* dictionaryFile;
size_t mutationsMax;
unsigned mutationsPerRun;
size_t maxInputSz;
} mutate;
struct {
bool useScreen;
char cmdline_txt[65];
int64_t lastDisplayUSecs;
} display;
struct {
bool useVerifier;
bool exitUponCrash;
const char* reportFile;
size_t dynFileIterExpire;
bool only_printable;
bool minimize;
bool switchingToFDM;
} cfg;
struct {
bool enable;
bool del_report;
} sanitizer;
struct {
fuzzState_t state;
feedback_t* covFeedbackMap;
int covFeedbackFd;
cmpfeedback_t* cmpFeedbackMap;
int cmpFeedbackFd;
bool cmpFeedback;
const char* blacklistFile;
uint64_t* blacklist;
size_t blacklistCnt;
bool skipFeedbackOnTimeout;
uint64_t maxCov[4];
dynFileMethod_t dynFileMethod;
hwcnt_t hwCnts;
} feedback;
struct {
size_t mutationsCnt;
size_t crashesCnt;
size_t uniqueCrashesCnt;
size_t verifiedCrashesCnt;
size_t blCrashesCnt;
size_t timeoutedCnt;
} cnts;
struct {
bool enabled;
int serverSocket;
int clientSocket;
} socketFuzzer;
struct {
pthread_rwlock_t dynfileq;
pthread_mutex_t feedback;
pthread_mutex_t report;
pthread_mutex_t state;
pthread_mutex_t input;
pthread_mutex_t timing;
} mutex;
/* For the Linux code */
struct {
int exeFd;
uint64_t dynamicCutOffAddr;
bool disableRandomization;
void* ignoreAddr;
const char* symsBlFile;
char** symsBl;
size_t symsBlCnt;
const char* symsWlFile;
char** symsWl;
size_t symsWlCnt;
uintptr_t cloneFlags;
tristate_t useNetNs;
bool kernelOnly;
bool useClone;
} arch_linux;
/* For the NetBSD code */
struct {
void* ignoreAddr;
const char* symsBlFile;
char** symsBl;
size_t symsBlCnt;
const char* symsWlFile;
char** symsWl;
size_t symsWlCnt;
} arch_netbsd;
} honggfuzz_t;
typedef enum {
_HF_RS_UNKNOWN = 0,
_HF_RS_WAITING_FOR_INITIAL_READY = 1,
_HF_RS_WAITING_FOR_READY = 2,
_HF_RS_SEND_DATA = 3,
} runState_t;
typedef struct {
honggfuzz_t* global;
pid_t pid;
int64_t timeStartedUSecs;
char crashFileName[PATH_MAX];
uint64_t pc;
uint64_t backtrace;
uint64_t access;
int exception;
char report[_HF_REPORT_SIZE];
bool mainWorker;
unsigned mutationsPerRun;
dynfile_t* dynfile;
bool staticFileTryMore;
uint32_t fuzzNo;
int persistentSock;
runState_t runState;
bool tmOutSignaled;
char* args[_HF_ARGS_MAX + 1];
int perThreadCovFeedbackFd;
unsigned triesLeft;
dynfile_t* current;
#if !defined(_HF_ARCH_DARWIN)
timer_t timerId;
#endif // !defined(_HF_ARCH_DARWIN)
hwcnt_t hwCnts;
struct {
/* For Linux code */
uint8_t* perfMmapBuf;
uint8_t* perfMmapAux;
int cpuInstrFd;
int cpuBranchFd;
int cpuIptBtsFd;
} arch_linux;
} run_t;
#endif