blob: 3cea8e71fae0169e0a31e05e2dd46a47830c92ea [file] [log] [blame]
robert.swiecki3bb518c2010-10-14 00:48:24 +00001/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00002 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00003 * honggfuzz - core structures and macros
4 * -----------------------------------------
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00005 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00006 * Author: Robert Swiecki <swiecki@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00007 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00008 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00009 *
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
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000012 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000013 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000014 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000015 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000016 * 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.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000021 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000022 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000023
24#ifndef _COMMON_H_
25#define _COMMON_H_
26
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000027#include <limits.h>
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +000028#include <pthread.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000029#include <stdbool.h>
30#include <stdint.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000031#include <sys/param.h>
32#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000033
Anestis Bechtsoudis2ff92d12015-12-20 15:33:20 +020034#ifndef UNUSED
35#define UNUSED __attribute__((unused))
36#endif
37
robert.swiecki3bb518c2010-10-14 00:48:24 +000038#define PROG_NAME "honggfuzz"
robert.swiecki@gmail.coma51662b2015-03-01 19:12:41 +000039#define PROG_VERSION "0.6rc"
robert.swiecki32b69c92015-02-26 14:56:36 +000040#define PROG_AUTHORS "Robert Swiecki <swiecki@google.com> et al.,\nCopyright 2010-2015 by Google Inc. All Rights Reserved."
robert.swiecki3bb518c2010-10-14 00:48:24 +000041
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000042/* Name of the template which will be replaced with the proper name of the file */
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +000043#define _HF_FILE_PLACEHOLDER "___FILE___"
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000044
45/* Default name of the report created with some architectures */
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000046#define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
robert.swiecki3bb518c2010-10-14 00:48:24 +000047
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000048/* Default stack-size of created threads. Must be bigger then _HF_DYNAMIC_FILE_MAX_SZ */
robert.swiecki@gmail.com23b3a2f2015-03-01 03:40:12 +000049#define _HF_PTHREAD_STACKSIZE (1024 * 1024 * 8) /* 8MB */
robert.swiecki@gmail.com01b6dd42015-02-16 18:11:28 +000050
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +000051/* Align to the upper-page boundary */
robert.swiecki87f7c7e2015-02-26 14:11:57 +000052#define _HF_PAGE_ALIGN_UP(x) (((size_t)x + (size_t)getpagesize() - (size_t)1) & ~((size_t)getpagesize() - (size_t)1))
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +000053
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +030054/* String buffer size for function names in stack traces produced from libunwind */
Jaggerd628a702015-08-23 12:59:37 +020055#define _HF_FUNC_NAME_SZ 256 // Should be alright for mangled C++ procs too
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +030056
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +030057/* Number of crash verifier iterations before tag crash as stable */
58#define _HF_VERIFIER_ITER 5
59
Anestis Bechtsoudis60ea5e72015-11-24 19:10:06 +020060/* Constant prefix used for single frame crashes stackhash masking */
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +020061#define _HF_SINGLE_FRAME_MASK 0xBADBAD0000000000
62
63/* Size (in bytes) for report data to be stored in stack before written to file */
64#define _HF_REPORT_SIZE 8192
Anestis Bechtsoudis0ef90002015-11-22 21:17:06 +020065
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +020066/*
67 * Maximum number of iterations to keep same base seed file for dynamic preparation.
68 * Maintained iterations counters is set to zero if unique crash is detected or
69 * zero-set two MSB using following mask if crash is detected (might not be unique).
70 */
71#define _HF_MAX_DYNFILE_ITER 0x2000UL
72#define _HF_DYNFILE_SUB_MASK 0xFFFUL // Zero-set two MSB
73
Anestis Bechtsoudisc34451a2016-01-07 12:36:22 +020074/*
75 * SIGABRT is not a monitored signal (thus 'abort_on_error' is missing crashes when set)
76 * for Android OS since it produces lots of useless crashes due to way Android process
77 * termination hacks work. Safest option is to register & monitor one of user signals.
78 * SIGUSR2 is used for sanitizer fuzzing in Android, although might need to be changed
79 * if target uses it for other purposes.
80 */
81#define _HF_ANDROID_ASAN_EXIT_SIG SIGUSR2
82
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +020083/* Bitmap size */
84#define _HF_BITMAP_SIZE 0xAFFFFF
85
86/* Directory in workspace to store sanitizer coverage data */
87#define _HF_SANCOV_DIR "HF_SANCOV"
88
89/* Uncomment/Comment to enable/disable debug */
90#define _HF_DEBUG 1
91
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +000092typedef enum {
robert.swiecki@gmail.com81e26dc2015-03-03 04:26:04 +000093 _HF_DYNFILE_NONE = 0x0,
94 _HF_DYNFILE_INSTR_COUNT = 0x1,
95 _HF_DYNFILE_BRANCH_COUNT = 0x2,
robert.swiecki@gmail.com10e69b62015-03-08 02:21:56 +000096 _HF_DYNFILE_UNIQUE_BLOCK_COUNT = 0x8,
97 _HF_DYNFILE_UNIQUE_EDGE_COUNT = 0x10,
robert.swiecki2a953692015-03-16 19:33:37 +000098 _HF_DYNFILE_CUSTOM = 0x20,
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +000099} dynFileMethod_t;
100
robert.swiecki3bb518c2010-10-14 00:48:24 +0000101typedef struct {
Jaggerb409ee12015-09-09 02:02:32 +0200102 uint64_t cpuInstrCnt;
103 uint64_t cpuBranchCnt;
104 uint64_t pcCnt;
105 uint64_t pathCnt;
106 uint64_t customCnt;
107} hwcnt_t;
108
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200109/* Sanitizer coverage specific data structures */
Jaggerb409ee12015-09-09 02:02:32 +0200110typedef struct {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200111 uint64_t hitPcCnt;
112 uint64_t totalPcCnt;
113 uint64_t dsoCnt;
114 uint64_t iDsoCnt;
115 uint64_t newPcCnt;
116 uint64_t crashesCnt;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200117} sancovcnt_t;
118
119typedef struct {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200120 uint32_t capacity;
121 uint32_t *pChunks;
122 uint32_t nChunks;
123} bitmap_t;
124
125/* Memory map struct */
126typedef struct __attribute__ ((packed)) {
127 uint64_t start; // region start addr
128 uint64_t end; // region end addr
129 uint64_t base; // region base addr
130 char mapName[NAME_MAX]; // bin/DSO name
131 uint64_t pcCnt;
132 uint64_t newPcCnt;
133} memMap_t;
134
135/* Trie node data struct */
136typedef struct __attribute__ ((packed)) {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200137 bitmap_t *pBM;
138} trieData_t;
139
140/* Trie node struct */
141typedef struct __attribute__ ((packed)) node {
142 char key;
143 trieData_t data;
144 struct node *next;
145 struct node *prev;
146 struct node *children;
147 struct node *parent;
148} node_t;
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200149
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200150/* EOF Sanitizer coverage specific data structures */
151
152typedef struct {
robert.swiecki3bb518c2010-10-14 00:48:24 +0000153 char **cmdline;
154 char *inputFile;
155 bool nullifyStdio;
156 bool fuzzStdin;
157 bool saveUnique;
Jagger0764ad72015-09-06 01:11:08 +0200158 bool useScreen;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300159 bool useVerifier;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000160 char *fileExtn;
Anestis Bechtsoudisd9680532015-09-06 17:37:05 +0300161 char *workDir;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000162 double flipRate;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000163 char *externalCommand;
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000164 const char *dictionaryFile;
165 const char **dictionary;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300166 const char *blacklistFile;
167 uint64_t *blacklist;
168 size_t blacklistCnt;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000169 long tmOut;
Jaggerea39a8f2015-09-05 00:57:22 +0200170 size_t dictionaryCnt;
171 size_t mutationsMax;
Jaggerea39a8f2015-09-05 00:57:22 +0200172 size_t threadsMax;
173 size_t threadsFinished;
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000174 size_t maxFileSz;
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000175 char *reportFile;
Robert Swieckic578d642015-09-08 16:13:36 +0200176 uint64_t asLimit;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000177 char **files;
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200178 size_t fileCnt;
179 size_t lastCheckedFileIndex;
robert.swiecki@gmail.com15eca6f2015-03-04 03:31:36 +0000180 pid_t pid;
181 char *envs[128];
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +0000182
Jagger630aa7f2015-09-06 02:53:51 +0200183 time_t timeStart;
Jagger0764ad72015-09-06 01:11:08 +0200184 size_t mutationsCnt;
185 size_t crashesCnt;
Anestis Bechtsoudisd7e8ed22015-09-10 18:29:34 +0300186 size_t uniqueCrashesCnt;
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200187 size_t verifiedCrashesCnt;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300188 size_t blCrashesCnt;
Jagger4b5281e2015-09-06 02:35:37 +0200189 size_t timeoutedCnt;
Jagger0764ad72015-09-06 01:11:08 +0200190
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000191 /* For the linux/ code */
robert.swiecki@gmail.comcd74cfc2015-02-19 16:37:49 +0000192 uint8_t *dynamicFileBest;
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +0000193 size_t dynamicFileBestSz;
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000194 dynFileMethod_t dynFileMethod;
Jaggerb409ee12015-09-09 02:02:32 +0200195 hwcnt_t hwCnts;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200196 sancovcnt_t sanCovCnts;
robert.swiecki@gmail.com684f60c2015-03-01 17:39:18 +0000197 uint64_t dynamicCutOffAddr;
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +0000198 pthread_mutex_t dynamicFile_mutex;
Jaggerdbc4a152015-09-08 01:26:58 +0200199 bool disableRandomization;
200 bool msanReportUMRS;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200201 void *ignoreAddr;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200202 bool useSanCov;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200203 node_t *covMetadata;
Anestis Bechtsoudis1fd10c72016-01-07 12:38:45 +0200204 bool clearCovMetadata;
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200205 size_t dynFileIterExpire;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200206 pthread_mutex_t sanCov_mutex;
Anestis Bechtsoudisac054802016-01-07 23:48:06 +0200207 pthread_mutex_t workersBlock_mutex;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200208#ifdef _HF_DEBUG
209 long maxSpentInSanCov;
210#endif
robert.swiecki3bb518c2010-10-14 00:48:24 +0000211} honggfuzz_t;
212
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000213typedef struct fuzzer_t {
214 pid_t pid;
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000215 int64_t timeStartedMillis;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000216 char origFileName[PATH_MAX];
217 char fileName[PATH_MAX];
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300218 char crashFileName[PATH_MAX];
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000219 uint64_t pc;
220 uint64_t backtrace;
221 uint64_t access;
222 int exception;
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +0200223 char report[_HF_REPORT_SIZE];
Anestis Bechtsoudis6b9e83d2015-10-02 11:10:50 -0700224 bool mainWorker;
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000225
226 /* For linux/ code */
robert.swiecki@gmail.comcd74cfc2015-02-19 16:37:49 +0000227 uint8_t *dynamicFile;
Jaggerb409ee12015-09-09 02:02:32 +0200228 hwcnt_t hwCnts;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200229 sancovcnt_t sanCovCnts;
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000230 size_t dynamicFileSz;
Anestis Bechtsoudisac054802016-01-07 23:48:06 +0200231 bool isDynFileLocked;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000232} fuzzer_t;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000233
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +0300234#define _HF_MAX_FUNCS 80
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +0000235typedef struct {
236 void *pc;
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +0300237 char func[_HF_FUNC_NAME_SZ];
238 size_t line;
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +0000239} funcs_t;
240
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000241#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
242
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200243#ifdef _HF_DEBUG
244#include <time.h>
245#if defined(_HF_ARCH_DARWIN)
246#include <mach/clock.h>
247#include <mach/mach.h>
248#endif
249
250static inline void currentUtcTime(struct timespec *ts)
251{
252#if defined(_HF_ARCH_DARWIN)
253 clock_serv_t cclock;
254 mach_timespec_t mts;
255 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
256 clock_get_time(cclock, &mts);
257 mach_port_deallocate(mach_task_self(), cclock);
258 ts->tv_sec = mts.tv_sec;
259 ts->tv_nsec = mts.tv_nsec;
260#else
261 clock_gettime(CLOCK_REALTIME, ts);
262#endif
263}
264
265static inline struct timespec startTimer()
266{
267 struct timespec startTime;
268 currentUtcTime(&startTime);
269 return startTime;
270}
271
272static inline long endTimer(struct timespec startTime)
273{
274 struct timespec endTime;
275 currentUtcTime(&endTime);
276 long diffNs = endTime.tv_nsec - startTime.tv_nsec;
277 return diffNs;
278}
279
280#define _HF_START_TIMER struct timespec t = startTimer();
281#define _HF_END_TIMER long diff = endTimer(t);
282#define _HF_PRINT_TIMER LOG_I("Time taken: %ld ns", diff);
283#define _HF_GET_TIME diff
284#endif
285
robert.swiecki3bb518c2010-10-14 00:48:24 +0000286#endif