summaryrefslogtreecommitdiff
path: root/honggfuzz.h
blob: 368520d1fa35d5ac510a5619c3e17a75f2ed99c3 (plain)
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
/*
 *
 * honggfuzz - core structures and macros
 * -----------------------------------------
 *
 * Author: Robert Swiecki <swiecki@google.com>
 *
 * Copyright 2010-2017 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 <stdbool.h>
#include <stdint.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <time.h>

#define PROG_NAME "honggfuzz"
#define PROG_VERSION "1.2"

/* 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 (1024 * 1024 * 2) /* 2MB */

/* Name of envvar which indicates sequential number of fuzzer */
#define _HF_THREAD_NO_ENV "HFUZZ_THREAD_NO"

/* 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 8192

/* Perf bitmap size */
#define _HF_PERF_BITMAP_SIZE_16M (1024U * 1024U * 16U)
#define _HF_PERF_BITMAP_BITSZ_MASK 0x7ffffff
/* Maximum number of PC guards (=trace-pc-guard) we support */
#define _HF_PC_GUARD_MAX (1024U * 1024U)

/* FD used to pass feedback bitmap a process */
#define _HF_BITMAP_FD 1022
/* FD used to pass data to a persistent process */
#define _HF_PERSISTENT_FD 1023
/* Maximum number of active fuzzing threads */
#define _HF_THREAD_MAX 1024U

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;

/* Sanitizer coverage specific data structures */
typedef struct {
    uint64_t hitBBCnt;
    uint64_t totalBBCnt;
    uint64_t dsoCnt;
    uint64_t iDsoCnt;
    uint64_t newBBCnt;
    uint64_t crashesCnt;
} sancovcnt_t;

typedef struct {
    uint32_t capacity;
    uint32_t* pChunks;
    uint32_t nChunks;
} bitmap_t;

/* Memory map struct */
typedef struct __attribute__((packed)) {
    uint64_t start;          // region start addr
    uint64_t end;            // region end addr
    uint64_t base;           // region base addr
    char mapName[NAME_MAX];  // bin/DSO name
    uint64_t bbCnt;
    uint64_t newBBCnt;
} memMap_t;

/* Trie node data struct */
typedef struct __attribute__((packed)) {
    bitmap_t* pBM;
} trieData_t;

/* Trie node struct */
typedef struct node {
    char key;
    trieData_t data;
    struct node* next;
    struct node* prev;
    struct node* children;
    struct node* parent;
} node_t;

/* EOF Sanitizer coverage specific data structures */

typedef struct {
    char* asanOpts;
    char* msanOpts;
    char* ubsanOpts;
} sanOpts_t;

typedef enum {
    _HF_STATE_UNSET = 0,
    _HF_STATE_STATIC = 1,
    _HF_STATE_DYNAMIC_PRE = 2,
    _HF_STATE_DYNAMIC_MAIN = 3,
} fuzzState_t;

struct dynfile_t {
    uint8_t* data;
    size_t size;
    TAILQ_ENTRY(dynfile_t)
    pointers;
};

struct strings_t {
    char* s;
    size_t len;
    TAILQ_ENTRY(strings_t)
    pointers;
};

typedef struct {
    bool pcGuardMap[_HF_PC_GUARD_MAX];
    uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M];
    uint8_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M];
    uint64_t pidFeedbackPc[_HF_THREAD_MAX];
    uint64_t pidFeedbackEdge[_HF_THREAD_MAX];
    uint64_t pidFeedbackCmp[_HF_THREAD_MAX];
} feedback_t;

typedef struct {
    char** cmdline;
    char cmdline_txt[61];
    bool nullifyStdio;
    bool fuzzStdin;
    bool saveUnique;
    bool useScreen;
    bool useVerifier;
    time_t timeStart;
    struct {
        char* inputDir;
        DIR* inputDirP;
        size_t fileCnt;
        char* fileExtn;
        bool fileCntDone;
        char* workDir;
        char* covDir;
    } io;
    unsigned mutationsPerRun;
    char* externalCommand;
    char* postExternalCommand;
    const char* blacklistFile;
    uint64_t* blacklist;
    size_t blacklistCnt;
    long tmOut;
    time_t runEndTime;
    size_t mutationsMax;
    size_t maxFileSz;
    char* reportFile;
    uint64_t asLimit;
    bool clearEnv;
    char* envs[128];
    bool persistent;
    bool tmout_vtalrm;
    bool skipFeedbackOnTimeout;
    bool enableSanitizers;
    bool monitorSIGABRT;
    bool terminating;
    bool exitUponCrash;

    struct {
        size_t threadsMax;
        size_t threadsFinished;
        uint32_t threadsActiveCnt;
        pthread_t mainThread;
        pid_t mainPid;
    } threads;

    const char* dictionaryFile;
    TAILQ_HEAD(strq_t, strings_t) dictq;
    size_t dictionaryCnt;
    struct strings_t* dictqCurrent;

    fuzzState_t state;
    feedback_t* feedback;
    int bbFd;

    size_t dynfileqCnt;
    TAILQ_HEAD(dyns_t, dynfile_t) dynfileq;
    pthread_rwlock_t dynfileq_mutex;

    pthread_mutex_t feedback_mutex;

    struct {
        size_t mutationsCnt;
        size_t crashesCnt;
        size_t uniqueCrashesCnt;
        size_t verifiedCrashesCnt;
        size_t blCrashesCnt;
        size_t timeoutedCnt;
    } cnts;

    dynFileMethod_t dynFileMethod;
    sancovcnt_t sanCovCnts;
    pthread_mutex_t sanCov_mutex;
    sanOpts_t sanOpts;
    size_t dynFileIterExpire;
    bool useSanCov;
    node_t* covMetadata;

    pthread_mutex_t report_mutex;

    /* For the Linux code */
    struct {
        int exeFd;
        hwcnt_t hwCnts;
        uint64_t dynamicCutOffAddr;
        bool disableRandomization;
        void* ignoreAddr;
        size_t numMajorFrames;
        pid_t pid;
        const char* pidFile;
        char* pidCmd;
        const char* symsBlFile;
        char** symsBl;
        size_t symsBlCnt;
        const char* symsWlFile;
        char** symsWl;
        size_t symsWlCnt;
        uintptr_t cloneFlags;
        bool kernelOnly;
        bool useClone;
    } linux;
} honggfuzz_t;

typedef struct {
    honggfuzz_t* global;
    pid_t pid;
    pid_t persistentPid;
    fuzzState_t state;
    int64_t timeStartedMillis;
    const char* origFileName;
    char fileName[PATH_MAX];
    char crashFileName[PATH_MAX];
    uint64_t pc;
    uint64_t backtrace;
    uint64_t access;
    int exception;
    char report[_HF_REPORT_SIZE];
    bool mainWorker;
    unsigned mutationsPerRun;
    struct dynfile_t* dynfileqCurrent;
    uint8_t* dynamicFile;
    size_t dynamicFileSz;
    uint32_t fuzzNo;
    int persistentSock;
    bool tmOutSignaled;
#if !defined(_HF_ARCH_DARWIN)
    timer_t timerId;
#endif  // !defined(_HF_ARCH_DARWIN)

    sancovcnt_t sanCovCnts;

    struct {
        /* For Linux code */
        uint8_t* perfMmapBuf;
        uint8_t* perfMmapAux;
        hwcnt_t hwCnts;
        pid_t attachedPid;
        int cpuInstrFd;
        int cpuBranchFd;
        int cpuIptBtsFd;
    } linux;
} run_t;

#endif