1 /*
2  *
3  * honggfuzz - core structures and macros
4  * -----------------------------------------
5  *
6  * Author: Robert Swiecki <swiecki@google.com>
7  *
8  * Copyright 2010-2015 by Google Inc. All Rights Reserved.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License"); you may
11  * not use this file except in compliance with the License. You may obtain
12  * a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
19  * implied. See the License for the specific language governing
20  * permissions and limitations under the License.
21  *
22  */
23 
24 #ifndef _HF_COMMON_H_
25 #define _HF_COMMON_H_
26 
27 #include <limits.h>
28 #include <pthread.h>
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <sys/param.h>
32 #include <sys/queue.h>
33 #include <sys/types.h>
34 
35 #ifdef __clang__
36 #include <stdatomic.h>
37 #endif
38 
39 #ifndef UNUSED
40 #define UNUSED __attribute__((unused))
41 #endif
42 
43 #define PROG_NAME "honggfuzz"
44 #define PROG_VERSION "0.6rc"
45 #define PROG_AUTHORS "Robert Swiecki <swiecki@google.com> et al.,\nCopyright 2010-2015 by Google Inc. All Rights Reserved."
46 
47 /* Go-style defer implementation */
48 #define __STRMERGE(a, b) a##b
49 #define _STRMERGE(a, b) __STRMERGE(a, b)
50 
51 #ifdef __clang__
52 static void __attribute__ ((unused)) _clang_cleanup_func(void (^*dfunc) (void))
53 {
54     (*dfunc) ();
55 }
56 
57 #define DEFER(a) void (^_STRMERGE(__defer_f_, __COUNTER__))(void) __attribute__((cleanup(_clang_cleanup_func))) __attribute__((unused)) = ^{ a; }
58 #else
59 #define __block
60 #define _DEFER(a, count) void _STRMERGE(__defer_f_, count)(void *_defer_arg __attribute__((unused))) { a; } ; \
61     int _STRMERGE(_defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) __attribute__((unused))
62 #define DEFER(a) _DEFER(a, __COUNTER__)
63 #endif
64 
65 /* Name of the template which will be replaced with the proper name of the file */
66 #define _HF_FILE_PLACEHOLDER "___FILE___"
67 
68 /* Default name of the report created with some architectures */
69 #define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
70 
71 /* Default stack-size of created threads. Must be bigger then _HF_DYNAMIC_FILE_MAX_SZ */
72 #define _HF_PTHREAD_STACKSIZE (1024 * 1024 * 8) /* 8MB */
73 
74 /* Align to the upper-page boundary */
75 #define _HF_PAGE_ALIGN_UP(x)  (((size_t)x + (size_t)getpagesize() - (size_t)1) & ~((size_t)getpagesize() - (size_t)1))
76 
77 /* String buffer size for function names in stack traces produced from libunwind */
78 #define _HF_FUNC_NAME_SZ    256 // Should be alright for mangled C++ procs too
79 
80 /* Number of crash verifier iterations before tag crash as stable */
81 #define _HF_VERIFIER_ITER   5
82 
83 /* Constant prefix used for single frame crashes stackhash masking */
84 #define _HF_SINGLE_FRAME_MASK  0xBADBAD0000000000
85 
86 /* Size (in bytes) for report data to be stored in stack before written to file */
87 #define _HF_REPORT_SIZE 8192
88 
89 #define _HF_DYNFILE_SUB_MASK 0xFFFUL    // Zero-set two MSB
90 
91 /* Bitmap size */
92 #define _HF_BITMAP_SIZE 0x2AFFFFF
93 
94 /* Perf bitmap size */
95 #define _HF_PERF_BITMAP_SIZE (1024U * 1024U * 1024U)
96 
97 /* Directory in workspace to store sanitizer coverage data */
98 #define _HF_SANCOV_DIR "HF_SANCOV"
99 
100 #if defined(__ANDROID__)
101 #define _HF_MONITOR_SIGABRT 0
102 #else
103 #define _HF_MONITOR_SIGABRT 1
104 #endif
105 
106 /* Size of remote pid cmdline char buffer */
107 #define _HF_PROC_CMDLINE_SZ 8192
108 
109 typedef enum {
110     _HF_DYNFILE_NONE = 0x0,
111     _HF_DYNFILE_INSTR_COUNT = 0x1,
112     _HF_DYNFILE_BRANCH_COUNT = 0x2,
113     _HF_DYNFILE_BTS_BLOCK = 0x8,
114     _HF_DYNFILE_BTS_EDGE = 0x10,
115     _HF_DYNFILE_IPT_BLOCK = 0x20,
116     _HF_DYNFILE_CUSTOM = 0x40,
117 } dynFileMethod_t;
118 
119 typedef struct {
120     uint64_t cpuInstrCnt;
121     uint64_t cpuBranchCnt;
122     uint64_t customCnt;
123     uint64_t bbCnt;
124 } hwcnt_t;
125 
126 /* Sanitizer coverage specific data structures */
127 typedef struct {
128     uint64_t hitBBCnt;
129     uint64_t totalBBCnt;
130     uint64_t dsoCnt;
131     uint64_t iDsoCnt;
132     uint64_t newBBCnt;
133     uint64_t crashesCnt;
134 } sancovcnt_t;
135 
136 typedef struct {
137     uint32_t capacity;
138     uint32_t *pChunks;
139     uint32_t nChunks;
140 } bitmap_t;
141 
142 /* Memory map struct */
143 typedef struct __attribute__ ((packed)) {
144     uint64_t start;             // region start addr
145     uint64_t end;               // region end addr
146     uint64_t base;              // region base addr
147     char mapName[NAME_MAX];     // bin/DSO name
148     uint64_t bbCnt;
149     uint64_t newBBCnt;
150 } memMap_t;
151 
152 /* Trie node data struct */
153 typedef struct __attribute__ ((packed)) {
154     bitmap_t *pBM;
155 } trieData_t;
156 
157 /* Trie node struct */
158 typedef struct __attribute__ ((packed)) node {
159     char key;
160     trieData_t data;
161     struct node *next;
162     struct node *prev;
163     struct node *children;
164     struct node *parent;
165 } node_t;
166 
167 /* EOF Sanitizer coverage specific data structures */
168 
169 typedef struct {
170     char *asanOpts;
171     char *msanOpts;
172     char *ubsanOpts;
173 } sanOpts_t;
174 
175 typedef enum {
176     _HF_STATE_UNSET = 0,
177     _HF_STATE_STATIC = 1,
178     _HF_STATE_DYNAMIC_PRE = 2,
179     _HF_STATE_DYNAMIC_MAIN = 3,
180 } fuzzState_t;
181 
182 struct dynfile_t {
183     uint8_t *data;
184     size_t size;
185      TAILQ_ENTRY(dynfile_t) pointers;
186 };
187 
188 typedef struct {
189     char **cmdline;
190     char cmdline_txt[PATH_MAX];
191     char *inputFile;
192     bool nullifyStdio;
193     bool fuzzStdin;
194     bool saveUnique;
195     bool useScreen;
196     bool useVerifier;
197     time_t timeStart;
198     char *fileExtn;
199     char *workDir;
200     double origFlipRate;
201     char *externalCommand;
202     const char *dictionaryFile;
203     char **dictionary;
204     const char *blacklistFile;
205     uint64_t *blacklist;
206     size_t blacklistCnt;
207     long tmOut;
208     size_t dictionaryCnt;
209     size_t mutationsMax;
210     size_t threadsMax;
211     size_t threadsFinished;
212     size_t maxFileSz;
213     char *reportFile;
214     uint64_t asLimit;
215     char **files;
216     size_t fileCnt;
217     size_t lastFileIndex;
218     size_t doneFileIndex;
219     int exeFd;
220     bool clearEnv;
221     char *envs[128];
222 
223     fuzzState_t state;
224     uint8_t *bbMap;
225     size_t bbMapSz;
226     size_t dynfileqCnt;
227     pthread_mutex_t dynfileq_mutex;
228      TAILQ_HEAD(dynfileq_t, dynfile_t) dynfileq;
229 
230     size_t mutationsCnt;
231     size_t crashesCnt;
232     size_t uniqueCrashesCnt;
233     size_t verifiedCrashesCnt;
234     size_t blCrashesCnt;
235     size_t timeoutedCnt;
236 
237     dynFileMethod_t dynFileMethod;
238     sancovcnt_t sanCovCnts;
239     pthread_mutex_t sanCov_mutex;
240     sanOpts_t sanOpts;
241     size_t dynFileIterExpire;
242     bool useSanCov;
243     node_t *covMetadata;
244 
245     /* For the Linux code */
246     hwcnt_t hwCnts;
247     uint64_t dynamicCutOffAddr;
248     bool disableRandomization;
249     bool msanReportUMRS;
250     void *ignoreAddr;
251     size_t numMajorFrames;
252     pid_t pid;
253     const char *pidFile;
254     char *pidCmd;
255 } honggfuzz_t;
256 
257 typedef struct fuzzer_t {
258     pid_t pid;
259     int64_t timeStartedMillis;
260     char origFileName[PATH_MAX];
261     char fileName[PATH_MAX];
262     char crashFileName[PATH_MAX];
263     uint64_t pc;
264     uint64_t backtrace;
265     uint64_t access;
266     int exception;
267     char report[_HF_REPORT_SIZE];
268     bool mainWorker;
269     float flipRate;
270 
271     sancovcnt_t sanCovCnts;
272     uint8_t *dynamicFile;
273     size_t dynamicFileSz;
274 
275     /* For Linux code */
276     hwcnt_t hwCnts;
277 } fuzzer_t;
278 
279 #define _HF_MAX_FUNCS 80
280 typedef struct {
281     void *pc;
282     char func[_HF_FUNC_NAME_SZ];
283     size_t line;
284 } funcs_t;
285 
286 #define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
287 
288 #define rmb()	__asm__ __volatile__("":::"memory")
289 #define wmb()	__sync_synchronize()
290 
291 #endif
292