blob: b05810088137130d0d3b99cd408db111a506265c [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
Jagger876a74c2016-02-09 22:09:11 +010024#ifndef _HF_COMMON_H_
25#define _HF_COMMON_H_
robert.swiecki3bb518c2010-10-14 00:48:24 +000026
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 Swiecki846ccd72017-01-12 17:52:23 +010029#include <inttypes.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000030#include <stdbool.h>
31#include <stdint.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000032#include <sys/param.h>
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010033#include <sys/queue.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000034#include <sys/types.h>
Robert Swiecki64d74252016-03-31 17:28:56 +020035#include <time.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000036
Anestis Bechtsoudis2ff92d12015-12-20 15:33:20 +020037#ifndef UNUSED
38#define UNUSED __attribute__((unused))
39#endif
40
robert.swiecki3bb518c2010-10-14 00:48:24 +000041#define PROG_NAME "honggfuzz"
Jaggere7af11e2016-09-27 10:06:22 +020042#define PROG_VERSION "0.9alpha"
robert.swiecki32b69c92015-02-26 14:56:36 +000043#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 +000044
Robert Swieckia9db9dd2016-03-09 16:29:37 +010045/* Go-style defer implementation */
46#define __STRMERGE(a, b) a##b
47#define _STRMERGE(a, b) __STRMERGE(a, b)
48
49#ifdef __clang__
Jagger4fe18692016-04-22 23:15:07 +020050static void __attribute__ ((unused)) __clang_cleanup_func(void (^*dfunc) (void))
Robert Swieckia9db9dd2016-03-09 16:29:37 +010051{
52 (*dfunc) ();
53}
54
Jagger4fe18692016-04-22 23:15:07 +020055#define defer void (^_STRMERGE(__defer_f_, __COUNTER__))(void) __attribute__((cleanup(__clang_cleanup_func))) __attribute__((unused)) = ^
Robert Swieckia9db9dd2016-03-09 16:29:37 +010056#else
57#define __block
Jagger4fe18692016-04-22 23:15:07 +020058#define _DEFER(a, count) \
59 auto void _STRMERGE(__defer_f_, count)(void *_defer_arg __attribute__((unused))); \
60 int _STRMERGE(__defer_var_, count) __attribute__((cleanup(_STRMERGE(__defer_f_, count)))) __attribute__((unused)); \
61 void _STRMERGE(__defer_f_, count)(void *_defer_arg __attribute__((unused)))
62#define defer _DEFER(a, __COUNTER__)
Robert Swieckia9db9dd2016-03-09 16:29:37 +010063#endif
64
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000065/* Name of the template which will be replaced with the proper name of the file */
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +000066#define _HF_FILE_PLACEHOLDER "___FILE___"
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000067
68/* Default name of the report created with some architectures */
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000069#define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
robert.swiecki3bb518c2010-10-14 00:48:24 +000070
Robert Swiecki3f03f7e2016-10-03 03:11:33 +020071/* Default stack-size of created threads. */
72#define _HF_PTHREAD_STACKSIZE (1024 * 1024 * 2) /* 2MB */
robert.swiecki@gmail.com01b6dd42015-02-16 18:11:28 +000073
Jaggerfa3544a2016-08-30 02:55:55 +020074/* Name of envvar which indicates sequential number of fuzzer */
75#define _HF_THREAD_NO_ENV "HFUZZ_THREAD_NO"
76
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +030077/* Number of crash verifier iterations before tag crash as stable */
78#define _HF_VERIFIER_ITER 5
79
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +020080/* Size (in bytes) for report data to be stored in stack before written to file */
81#define _HF_REPORT_SIZE 8192
Anestis Bechtsoudis0ef90002015-11-22 21:17:06 +020082
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010083/* Perf bitmap size */
Jagger3d977522016-08-21 19:15:59 +020084#define _HF_PERF_BITMAP_SIZE_16M (1024U * 1024U * 16U)
Robert Swieckibadab612016-09-08 18:31:10 +020085#define _HF_PERF_BITMAP_BITSZ_MASK 0x7ffffff
Robert Swiecki7c2c90c2016-10-04 02:47:38 +020086/* Maximum number of PC guards (=trace-pc-guard) we support */
87#define _HF_PC_GUARD_MAX (1024U * 1024U)
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010088
Jaggerd34417d2016-03-16 01:26:54 +010089#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
90
91/* Memory barriers */
92#define rmb() __asm__ __volatile__("":::"memory")
93#define wmb() __sync_synchronize()
94
Jagger9a135bb2016-08-21 21:37:06 +020095/* FD used to pass feedback bitmap a process */
96#define _HF_BITMAP_FD 1022
97/* FD used to pass data to a persistent process */
98#define _HF_PERSISTENT_FD 1023
99
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000100typedef enum {
robert.swiecki@gmail.com81e26dc2015-03-03 04:26:04 +0000101 _HF_DYNFILE_NONE = 0x0,
102 _HF_DYNFILE_INSTR_COUNT = 0x1,
103 _HF_DYNFILE_BRANCH_COUNT = 0x2,
Jagger3abc5602016-02-04 00:53:43 +0100104 _HF_DYNFILE_BTS_BLOCK = 0x8,
105 _HF_DYNFILE_BTS_EDGE = 0x10,
Jagger39bd2b02016-02-04 01:16:15 +0100106 _HF_DYNFILE_IPT_BLOCK = 0x20,
Robert Swiecki60cdf522016-11-01 14:31:15 +0100107 _HF_DYNFILE_SOFT = 0x40,
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000108} dynFileMethod_t;
109
robert.swiecki3bb518c2010-10-14 00:48:24 +0000110typedef struct {
Jaggerb409ee12015-09-09 02:02:32 +0200111 uint64_t cpuInstrCnt;
112 uint64_t cpuBranchCnt;
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100113 uint64_t bbCnt;
Robert Swieckiac56a502016-03-17 18:59:46 +0100114 uint64_t newBBCnt;
Jagger34789a72016-09-08 00:36:09 +0200115 uint64_t softCntPc;
116 uint64_t softCntCmp;
Jaggerb409ee12015-09-09 02:02:32 +0200117} hwcnt_t;
118
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200119/* Sanitizer coverage specific data structures */
Jaggerb409ee12015-09-09 02:02:32 +0200120typedef struct {
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200121 uint64_t hitBBCnt;
122 uint64_t totalBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200123 uint64_t dsoCnt;
124 uint64_t iDsoCnt;
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200125 uint64_t newBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200126 uint64_t crashesCnt;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200127} sancovcnt_t;
128
129typedef struct {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200130 uint32_t capacity;
131 uint32_t *pChunks;
132 uint32_t nChunks;
133} bitmap_t;
134
135/* Memory map struct */
136typedef struct __attribute__ ((packed)) {
137 uint64_t start; // region start addr
138 uint64_t end; // region end addr
139 uint64_t base; // region base addr
140 char mapName[NAME_MAX]; // bin/DSO name
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200141 uint64_t bbCnt;
142 uint64_t newBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200143} memMap_t;
144
145/* Trie node data struct */
146typedef struct __attribute__ ((packed)) {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200147 bitmap_t *pBM;
148} trieData_t;
149
150/* Trie node struct */
Jagger7855f6b2016-08-31 22:21:33 +0200151typedef struct node {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200152 char key;
153 trieData_t data;
154 struct node *next;
155 struct node *prev;
156 struct node *children;
157 struct node *parent;
158} node_t;
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200159
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200160/* EOF Sanitizer coverage specific data structures */
161
162typedef struct {
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200163 char *asanOpts;
164 char *msanOpts;
165 char *ubsanOpts;
166} sanOpts_t;
167
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100168typedef enum {
169 _HF_STATE_UNSET = 0,
170 _HF_STATE_STATIC = 1,
171 _HF_STATE_DYNAMIC_PRE = 2,
172 _HF_STATE_DYNAMIC_MAIN = 3,
173} fuzzState_t;
174
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100175struct dynfile_t {
176 uint8_t *data;
177 size_t size;
Robert Swiecki7084e652016-03-14 19:47:00 +0100178 TAILQ_ENTRY(dynfile_t) pointers;
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100179};
180
Robert Swiecki531438a2016-09-13 19:05:11 +0200181struct strings_t {
182 char *s;
Jaggerc64c9eb2016-09-22 04:04:34 +0200183 size_t len;
Robert Swiecki531438a2016-09-13 19:05:11 +0200184 TAILQ_ENTRY(strings_t) pointers;
185};
186
Robert Swieckie8f8e8d2016-10-03 23:51:32 +0200187struct paths_t {
188 char path[PATH_MAX];
189 TAILQ_ENTRY(paths_t) pointers;
190};
191
Jaggerfa3544a2016-08-30 02:55:55 +0200192/* Maximum number of active fuzzing threads */
Robert Swiecki71b73722016-09-05 15:18:25 +0200193#define _HF_THREAD_MAX 1024U
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200194typedef struct {
Robert Swiecki7c2c90c2016-10-04 02:47:38 +0200195 bool pcGuardMap[_HF_PC_GUARD_MAX];
Jagger34789a72016-09-08 00:36:09 +0200196 uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M];
197 uint8_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M];
198 uint64_t pidFeedbackPc[_HF_THREAD_MAX];
199 uint64_t pidFeedbackCmp[_HF_THREAD_MAX];
Robert Swiecki4f4e8292016-08-23 17:46:32 +0200200} feedback_t;
Jaggerb7fa3ee2016-08-21 19:46:26 +0200201
202typedef struct {
robert.swiecki3bb518c2010-10-14 00:48:24 +0000203 char **cmdline;
Robert Swieckif2d9c3a2016-11-03 02:13:54 +0100204 char cmdline_txt[61];
Jagger1b2d4822016-09-25 16:19:45 +0200205 char *inputDir;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000206 bool nullifyStdio;
207 bool fuzzStdin;
208 bool saveUnique;
Jagger0764ad72015-09-06 01:11:08 +0200209 bool useScreen;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300210 bool useVerifier;
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100211 time_t timeStart;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000212 char *fileExtn;
Anestis Bechtsoudisd9680532015-09-06 17:37:05 +0300213 char *workDir;
Jagger1b2d4822016-09-25 16:19:45 +0200214 char *covDir;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100215 double origFlipRate;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000216 char *externalCommand;
Robert Swieckiee266ac2016-10-03 02:25:59 +0200217 char *postExternalCommand;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300218 const char *blacklistFile;
219 uint64_t *blacklist;
220 size_t blacklistCnt;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000221 long tmOut;
Jaggerea39a8f2015-09-05 00:57:22 +0200222 size_t mutationsMax;
Jaggerea39a8f2015-09-05 00:57:22 +0200223 size_t threadsMax;
224 size_t threadsFinished;
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000225 size_t maxFileSz;
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000226 char *reportFile;
Robert Swieckic578d642015-09-08 16:13:36 +0200227 uint64_t asLimit;
Robert Swiecki3a572262016-10-04 01:48:34 +0200228 TAILQ_HEAD(, paths_t) fileq;
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200229 size_t fileCnt;
Robert Swiecki05354ca2016-03-15 19:10:23 +0100230 size_t lastFileIndex;
231 size_t doneFileIndex;
Jagger80041fe2016-03-10 21:32:35 +0100232 bool clearEnv;
robert.swiecki@gmail.com15eca6f2015-03-04 03:31:36 +0000233 char *envs[128];
Robert Swiecki0f937af2016-03-30 18:19:16 +0200234 bool persistent;
Robert Swieckie84b6452016-12-12 12:42:04 +0100235 bool tmout_vtalrm;
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200236 bool enableSanitizers;
237 bool monitorSIGABRT;
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +0000238
Robert Swiecki531438a2016-09-13 19:05:11 +0200239 const char *dictionaryFile;
Robert Swiecki3a572262016-10-04 01:48:34 +0200240 TAILQ_HEAD(, strings_t) dictq;
Robert Swiecki531438a2016-09-13 19:05:11 +0200241 size_t dictionaryCnt;
242
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100243 fuzzState_t state;
Jaggerb7fa3ee2016-08-21 19:46:26 +0200244 feedback_t *feedback;
Robert Swieckibc7532e2016-08-20 00:34:17 +0200245 int bbFd;
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100246 size_t dynfileqCnt;
Robert Swieckie586c1f2016-03-14 18:46:03 +0100247 pthread_mutex_t dynfileq_mutex;
Robert Swiecki3a572262016-10-04 01:48:34 +0200248 TAILQ_HEAD(, dynfile_t) dynfileq;
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100249
Jagger0764ad72015-09-06 01:11:08 +0200250 size_t mutationsCnt;
251 size_t crashesCnt;
Anestis Bechtsoudisd7e8ed22015-09-10 18:29:34 +0300252 size_t uniqueCrashesCnt;
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200253 size_t verifiedCrashesCnt;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300254 size_t blCrashesCnt;
Jagger4b5281e2015-09-06 02:35:37 +0200255 size_t timeoutedCnt;
Jagger0764ad72015-09-06 01:11:08 +0200256
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000257 dynFileMethod_t dynFileMethod;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200258 sancovcnt_t sanCovCnts;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200259 pthread_mutex_t sanCov_mutex;
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200260 sanOpts_t sanOpts;
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100261 size_t dynFileIterExpire;
262 bool useSanCov;
263 node_t *covMetadata;
Jagger247c3b42016-03-21 23:24:05 +0100264 bool msanReportUMRS;
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100265
Haris Andrianakisc9a71332016-05-09 21:56:30 -0700266 pthread_mutex_t report_mutex;
267
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100268 /* For the Linux code */
Jagger247c3b42016-03-21 23:24:05 +0100269 struct {
270 hwcnt_t hwCnts;
271 uint64_t dynamicCutOffAddr;
272 bool disableRandomization;
273 void *ignoreAddr;
274 size_t numMajorFrames;
275 pid_t pid;
276 const char *pidFile;
277 char *pidCmd;
Anestis Bechtsoudisba68b382016-10-29 20:44:15 +0300278 const char *symsBlFile;
279 char **symsBl;
280 size_t symsBlCnt;
281 const char *symsWlFile;
282 char **symsWl;
283 size_t symsWlCnt;
Robert Swiecki846ccd72017-01-12 17:52:23 +0100284 uintptr_t cloneFlags;
Jagger247c3b42016-03-21 23:24:05 +0100285 } linux;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000286} honggfuzz_t;
287
Jaggere6be75c2016-03-17 03:18:04 +0100288typedef struct {
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000289 pid_t pid;
Robert Swieckidecf14b2016-03-31 15:09:28 +0200290 pid_t persistentPid;
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000291 int64_t timeStartedMillis;
Robert Swieckidecf14b2016-03-31 15:09:28 +0200292 const char *origFileName;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000293 char fileName[PATH_MAX];
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300294 char crashFileName[PATH_MAX];
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000295 uint64_t pc;
296 uint64_t backtrace;
297 uint64_t access;
298 int exception;
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +0200299 char report[_HF_REPORT_SIZE];
Anestis Bechtsoudis6b9e83d2015-10-02 11:10:50 -0700300 bool mainWorker;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100301 float flipRate;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100302 uint8_t *dynamicFile;
303 size_t dynamicFileSz;
Jaggerfa3544a2016-08-30 02:55:55 +0200304 uint32_t fuzzNo;
Jagger93253f72016-09-01 22:40:12 +0200305 int persistentSock;
Robert Swiecki013bc9c2016-12-12 17:31:06 +0100306 bool tmOutSignaled;
Jagger2c1a6912016-09-04 03:37:06 +0200307#if !defined(_HF_ARCH_DARWIN)
Jaggerf159a152016-09-02 02:22:09 +0200308 timer_t timerId;
Jagger2c1a6912016-09-04 03:37:06 +0200309#endif // !defined(_HF_ARCH_DARWIN)
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000310
Robert Swieckidecf14b2016-03-31 15:09:28 +0200311 sancovcnt_t sanCovCnts;
312
Jagger2381ef42016-03-20 23:32:05 +0100313 struct {
314 /* For Linux code */
Jagger2381ef42016-03-20 23:32:05 +0100315 uint8_t *perfMmapBuf;
316 uint8_t *perfMmapAux;
Robert Swieckidecf14b2016-03-31 15:09:28 +0200317 hwcnt_t hwCnts;
Robert Swiecki12800cd2016-03-31 15:38:10 +0200318 pid_t attachedPid;
Jagger98f0a0a2016-09-02 01:00:52 +0200319 int cpuInstrFd;
320 int cpuBranchFd;
321 int cpuIptBtsFd;
Jagger2381ef42016-03-20 23:32:05 +0100322 } linux;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000323} fuzzer_t;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000324
robert.swiecki3bb518c2010-10-14 00:48:24 +0000325#endif