blob: f5c75632a5993fe62328c10fbe18887cdbbff233 [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.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 Bechtsoudis4d9e8c92016-01-31 16:18:48 +020034#ifdef __clang__
35#include <stdatomic.h>
36#endif
37
Anestis Bechtsoudis2ff92d12015-12-20 15:33:20 +020038#ifndef UNUSED
39#define UNUSED __attribute__((unused))
40#endif
41
robert.swiecki3bb518c2010-10-14 00:48:24 +000042#define PROG_NAME "honggfuzz"
robert.swiecki@gmail.coma51662b2015-03-01 19:12:41 +000043#define PROG_VERSION "0.6rc"
robert.swiecki32b69c92015-02-26 14:56:36 +000044#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 +000045
Robert Swieckia9db9dd2016-03-09 16:29:37 +010046/* Go-style defer implementation */
47#define __STRMERGE(a, b) a##b
48#define _STRMERGE(a, b) __STRMERGE(a, b)
49
50#ifdef __clang__
51static void __attribute__ ((unused)) _clang_cleanup_func(void (^*dfunc) (void))
52{
53 (*dfunc) ();
54}
55
56#define defer(a) void (^_STRMERGE(__df_, __COUNTER__))(void) __attribute__((cleanup(_clang_cleanup_func))) __attribute__((unused)) = ^{ a; }
57#else
58#define __block
59#define defer(a) void _STRMERGE(_cleanup_func_, __LINE__)(void *_STRMERGE(_cleanup_unused_, __LINE__) __attribute__((unused))) { a; } ; int _STRMERGE(_cleanup_var_, __LINE__) __attribute__((cleanup(_STRMERGE(_cleanup_func_, __LINE__)))) __attribute__((unused))
60#endif
61
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000062/* Name of the template which will be replaced with the proper name of the file */
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +000063#define _HF_FILE_PLACEHOLDER "___FILE___"
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000064
65/* Default name of the report created with some architectures */
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000066#define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT"
robert.swiecki3bb518c2010-10-14 00:48:24 +000067
robert.swiecki@gmail.com64dc2a02015-02-17 22:21:30 +000068/* Default stack-size of created threads. Must be bigger then _HF_DYNAMIC_FILE_MAX_SZ */
robert.swiecki@gmail.com23b3a2f2015-03-01 03:40:12 +000069#define _HF_PTHREAD_STACKSIZE (1024 * 1024 * 8) /* 8MB */
robert.swiecki@gmail.com01b6dd42015-02-16 18:11:28 +000070
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +000071/* Align to the upper-page boundary */
robert.swiecki87f7c7e2015-02-26 14:11:57 +000072#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 +000073
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +030074/* String buffer size for function names in stack traces produced from libunwind */
Jaggerd628a702015-08-23 12:59:37 +020075#define _HF_FUNC_NAME_SZ 256 // Should be alright for mangled C++ procs too
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +030076
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 Bechtsoudis60ea5e72015-11-24 19:10:06 +020080/* Constant prefix used for single frame crashes stackhash masking */
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +020081#define _HF_SINGLE_FRAME_MASK 0xBADBAD0000000000
82
83/* Size (in bytes) for report data to be stored in stack before written to file */
84#define _HF_REPORT_SIZE 8192
Anestis Bechtsoudis0ef90002015-11-22 21:17:06 +020085
Robert Swiecki72d2bef2016-01-19 14:39:26 +010086/*
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +020087 * Maximum number of iterations to keep same base seed file for dynamic preparation.
88 * Maintained iterations counters is set to zero if unique crash is detected or
89 * zero-set two MSB using following mask if crash is detected (might not be unique).
90 */
91#define _HF_MAX_DYNFILE_ITER 0x2000UL
92#define _HF_DYNFILE_SUB_MASK 0xFFFUL // Zero-set two MSB
93
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +020094/* Bitmap size */
Robert Swiecki94335d62016-01-26 17:06:20 +010095#define _HF_BITMAP_SIZE 0x2AFFFFF
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +020096
97/* Directory in workspace to store sanitizer coverage data */
98#define _HF_SANCOV_DIR "HF_SANCOV"
99
Anestis Bechtsoudis8e634c32016-01-13 13:07:26 +0200100#if defined(__ANDROID__)
101#define _HF_MONITOR_SIGABRT 0
102#else
103#define _HF_MONITOR_SIGABRT 1
104#endif
105
Anestis Bechtsoudis7c88d7a2016-02-09 17:55:38 +0200106/* Size of remote pid cmdline char buffer */
107#define _HF_PROC_CMDLINE_SZ 8192
108
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000109typedef enum {
robert.swiecki@gmail.com81e26dc2015-03-03 04:26:04 +0000110 _HF_DYNFILE_NONE = 0x0,
111 _HF_DYNFILE_INSTR_COUNT = 0x1,
112 _HF_DYNFILE_BRANCH_COUNT = 0x2,
Jagger3abc5602016-02-04 00:53:43 +0100113 _HF_DYNFILE_BTS_BLOCK = 0x8,
114 _HF_DYNFILE_BTS_EDGE = 0x10,
Jagger39bd2b02016-02-04 01:16:15 +0100115 _HF_DYNFILE_IPT_BLOCK = 0x20,
Jagger0d2727a2016-02-08 02:08:42 +0100116 _HF_DYNFILE_CUSTOM = 0x40,
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000117} dynFileMethod_t;
118
robert.swiecki3bb518c2010-10-14 00:48:24 +0000119typedef struct {
Jaggerb409ee12015-09-09 02:02:32 +0200120 uint64_t cpuInstrCnt;
121 uint64_t cpuBranchCnt;
Jagger39bd2b02016-02-04 01:16:15 +0100122 uint64_t cpuBtsBlockCnt;
123 uint64_t cpuBtsEdgeCnt;
124 uint64_t cpuIptBlockCnt;
Jaggerb409ee12015-09-09 02:02:32 +0200125 uint64_t customCnt;
126} hwcnt_t;
127
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200128/* Sanitizer coverage specific data structures */
Jaggerb409ee12015-09-09 02:02:32 +0200129typedef struct {
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200130 uint64_t hitBBCnt;
131 uint64_t totalBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200132 uint64_t dsoCnt;
133 uint64_t iDsoCnt;
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200134 uint64_t newBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200135 uint64_t crashesCnt;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200136} sancovcnt_t;
137
138typedef struct {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200139 uint32_t capacity;
140 uint32_t *pChunks;
141 uint32_t nChunks;
142} bitmap_t;
143
144/* Memory map struct */
145typedef struct __attribute__ ((packed)) {
146 uint64_t start; // region start addr
147 uint64_t end; // region end addr
148 uint64_t base; // region base addr
149 char mapName[NAME_MAX]; // bin/DSO name
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200150 uint64_t bbCnt;
151 uint64_t newBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200152} memMap_t;
153
154/* Trie node data struct */
155typedef struct __attribute__ ((packed)) {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200156 bitmap_t *pBM;
157} trieData_t;
158
159/* Trie node struct */
160typedef struct __attribute__ ((packed)) node {
161 char key;
162 trieData_t data;
163 struct node *next;
164 struct node *prev;
165 struct node *children;
166 struct node *parent;
167} node_t;
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200168
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200169/* EOF Sanitizer coverage specific data structures */
170
171typedef struct {
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200172 char *asanOpts;
173 char *msanOpts;
174 char *ubsanOpts;
175} sanOpts_t;
176
177typedef struct {
robert.swiecki3bb518c2010-10-14 00:48:24 +0000178 char **cmdline;
Robert Swiecki72d2bef2016-01-19 14:39:26 +0100179 char cmdline_txt[PATH_MAX];
robert.swiecki3bb518c2010-10-14 00:48:24 +0000180 char *inputFile;
181 bool nullifyStdio;
182 bool fuzzStdin;
183 bool saveUnique;
Jagger0764ad72015-09-06 01:11:08 +0200184 bool useScreen;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300185 bool useVerifier;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000186 char *fileExtn;
Anestis Bechtsoudisd9680532015-09-06 17:37:05 +0300187 char *workDir;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000188 double flipRate;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000189 char *externalCommand;
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000190 const char *dictionaryFile;
Anestis Bechtsoudis70f2fbd2016-01-14 13:15:19 +0200191 char **dictionary;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300192 const char *blacklistFile;
193 uint64_t *blacklist;
194 size_t blacklistCnt;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000195 long tmOut;
Jaggerea39a8f2015-09-05 00:57:22 +0200196 size_t dictionaryCnt;
197 size_t mutationsMax;
Jaggerea39a8f2015-09-05 00:57:22 +0200198 size_t threadsMax;
199 size_t threadsFinished;
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000200 size_t maxFileSz;
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000201 char *reportFile;
Robert Swieckic578d642015-09-08 16:13:36 +0200202 uint64_t asLimit;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000203 char **files;
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200204 size_t fileCnt;
205 size_t lastCheckedFileIndex;
Jaggercdbf6852016-02-07 22:06:02 +0100206 int exeFd;
robert.swiecki@gmail.com15eca6f2015-03-04 03:31:36 +0000207 char *envs[128];
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +0000208
Jagger630aa7f2015-09-06 02:53:51 +0200209 time_t timeStart;
Jagger0764ad72015-09-06 01:11:08 +0200210 size_t mutationsCnt;
211 size_t crashesCnt;
Anestis Bechtsoudisd7e8ed22015-09-10 18:29:34 +0300212 size_t uniqueCrashesCnt;
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200213 size_t verifiedCrashesCnt;
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300214 size_t blCrashesCnt;
Jagger4b5281e2015-09-06 02:35:37 +0200215 size_t timeoutedCnt;
Jagger0764ad72015-09-06 01:11:08 +0200216
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200217 /* For the Linux code */
robert.swiecki@gmail.comcd74cfc2015-02-19 16:37:49 +0000218 uint8_t *dynamicFileBest;
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +0000219 size_t dynamicFileBestSz;
robert.swiecki@gmail.comcac22fd2015-02-19 14:03:28 +0000220 dynFileMethod_t dynFileMethod;
Jaggerb409ee12015-09-09 02:02:32 +0200221 hwcnt_t hwCnts;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200222 sancovcnt_t sanCovCnts;
robert.swiecki@gmail.com684f60c2015-03-01 17:39:18 +0000223 uint64_t dynamicCutOffAddr;
robert.swiecki@gmail.com41d8e052015-02-19 01:10:41 +0000224 pthread_mutex_t dynamicFile_mutex;
Jaggerdbc4a152015-09-08 01:26:58 +0200225 bool disableRandomization;
226 bool msanReportUMRS;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200227 void *ignoreAddr;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200228 bool useSanCov;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200229 node_t *covMetadata;
Anestis Bechtsoudis1fd10c72016-01-07 12:38:45 +0200230 bool clearCovMetadata;
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200231 size_t dynFileIterExpire;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200232 pthread_mutex_t sanCov_mutex;
Anestis Bechtsoudisac054802016-01-07 23:48:06 +0200233 pthread_mutex_t workersBlock_mutex;
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200234 sanOpts_t sanOpts;
Anestis Bechtsoudisa1b0a652016-01-08 16:14:55 +0200235 size_t numMajorFrames;
Anestis Bechtsoudisa1f8a032016-01-14 16:45:30 +0200236 bool isDynFileLocked;
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200237 pid_t pid;
238 const char *pidFile;
Anestis Bechtsoudis7c88d7a2016-02-09 17:55:38 +0200239 char *pidCmd;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000240} honggfuzz_t;
241
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000242typedef struct fuzzer_t {
243 pid_t pid;
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000244 int64_t timeStartedMillis;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000245 char origFileName[PATH_MAX];
246 char fileName[PATH_MAX];
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300247 char crashFileName[PATH_MAX];
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000248 uint64_t pc;
249 uint64_t backtrace;
250 uint64_t access;
251 int exception;
Anestis Bechtsoudisc06f8b32015-12-26 14:48:05 +0200252 char report[_HF_REPORT_SIZE];
Anestis Bechtsoudis6b9e83d2015-10-02 11:10:50 -0700253 bool mainWorker;
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000254
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200255 /* For Linux code */
robert.swiecki@gmail.comcd74cfc2015-02-19 16:37:49 +0000256 uint8_t *dynamicFile;
Jaggerb409ee12015-09-09 02:02:32 +0200257 hwcnt_t hwCnts;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200258 sancovcnt_t sanCovCnts;
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000259 size_t dynamicFileSz;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000260} fuzzer_t;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000261
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +0300262#define _HF_MAX_FUNCS 80
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +0000263typedef struct {
264 void *pc;
Anestis Bechtsoudiscfc39fb2015-08-06 10:31:36 +0300265 char func[_HF_FUNC_NAME_SZ];
266 size_t line;
robert.swiecki@gmail.coma0d87142015-02-14 13:11:18 +0000267} funcs_t;
268
robert.swiecki@gmail.com4da86bf2015-02-22 14:24:58 +0000269#define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
270
Jaggercc42cd62016-02-06 17:43:39 +0100271#define rmb() __asm__ __volatile__("":::"memory")
272#define wmb() __sync_synchronize()
273
robert.swiecki3bb518c2010-10-14 00:48:24 +0000274#endif