1 /* 2 * 3 * honggfuzz - core structures and macros 4 * ----------------------------------------- 5 * 6 * Author: Robert Swiecki <swiecki@google.com> 7 * 8 * Copyright 2010-2018 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_HONGGFUZZ_H_ 25 #define _HF_HONGGFUZZ_H_ 26 27 #include <dirent.h> 28 #include <inttypes.h> 29 #include <limits.h> 30 #include <pthread.h> 31 #include <signal.h> 32 #include <stdbool.h> 33 #include <stdint.h> 34 #include <sys/param.h> 35 #include <sys/queue.h> 36 #include <sys/types.h> 37 #include <time.h> 38 39 #include "libhfcommon/util.h" 40 41 #define PROG_NAME "honggfuzz" 42 #define PROG_VERSION "2.4" 43 44 /* Name of the template which will be replaced with the proper name of the file */ 45 #define _HF_FILE_PLACEHOLDER "___FILE___" 46 47 /* Default name of the report created with some architectures */ 48 #define _HF_REPORT_FILE "HONGGFUZZ.REPORT.TXT" 49 50 /* Default stack-size of created threads. */ 51 #define _HF_PTHREAD_STACKSIZE (1024ULL * 1024ULL * 2ULL) /* 2MB */ 52 53 /* Name of envvar which indicates sequential number of fuzzer */ 54 #define _HF_THREAD_NO_ENV "HFUZZ_THREAD_NO" 55 56 /* Name of envvar which indicates that the netDriver should be used */ 57 #define _HF_THREAD_NETDRIVER_ENV "HFUZZ_USE_NETDRIVER" 58 59 /* Name of envvar which indicates honggfuzz's log level in use */ 60 #define _HF_LOG_LEVEL_ENV "HFUZZ_LOG_LEVEL" 61 62 /* Number of crash verifier iterations before tag crash as stable */ 63 #define _HF_VERIFIER_ITER 5 64 65 /* Size (in bytes) for report data to be stored in stack before written to file */ 66 #define _HF_REPORT_SIZE 32768 67 68 /* Perf bitmap size */ 69 #define _HF_PERF_BITMAP_SIZE_16M (1024U * 1024U * 16U) 70 #define _HF_PERF_BITMAP_BITSZ_MASK 0x7FFFFFFULL 71 /* Maximum number of PC guards (=trace-pc-guard) we support */ 72 #define _HF_PC_GUARD_MAX (1024ULL * 1024ULL * 64ULL) 73 74 /* Maximum size of the input file in bytes (1 MiB) */ 75 #define _HF_INPUT_MAX_SIZE (1024ULL * 1024ULL) 76 77 /* Default maximum size of produced inputs */ 78 #define _HF_INPUT_DEFAULT_SIZE (1024ULL * 8) 79 80 /* Per-thread bitmap */ 81 #define _HF_PERTHREAD_BITMAP_FD 1018 82 /* FD used to report back used int/str constants from the fuzzed process */ 83 #define _HF_CMP_BITMAP_FD 1019 84 /* FD used to log inside the child process */ 85 #define _HF_LOG_FD 1020 86 /* FD used to represent the input file */ 87 #define _HF_INPUT_FD 1021 88 /* FD used to pass coverage feedback from the fuzzed process */ 89 #define _HF_COV_BITMAP_FD 1022 90 #define _HF_BITMAP_FD _HF_COV_BITMAP_FD /* Old name for _HF_COV_BITMAP_FD */ 91 /* FD used to pass data to a persistent process */ 92 #define _HF_PERSISTENT_FD 1023 93 94 /* Input file as a string */ 95 #define _HF_INPUT_FILE_PATH "/dev/fd/" HF_XSTR(_HF_INPUT_FD) 96 97 /* Maximum number of supported execve() args */ 98 #define _HF_ARGS_MAX 2048 99 100 /* Message indicating that the fuzzed process is ready for new data */ 101 static const uint8_t HFReadyTag = 'R'; 102 103 /* Maximum number of active fuzzing threads */ 104 #define _HF_THREAD_MAX 1024U 105 106 /* Persistent-binary signature - if found within file, it means it's a persistent mode binary */ 107 #define _HF_PERSISTENT_SIG "\x01_LIBHFUZZ_PERSISTENT_BINARY_SIGNATURE_\x02\xFF" 108 /* HF NetDriver signature - if found within file, it means it's a NetDriver-based binary */ 109 #define _HF_NETDRIVER_SIG "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF" 110 111 /* printf() nonmonetary separator. According to MacOSX's man it's supported there as well */ 112 #define _HF_NONMON_SEP "'" 113 114 typedef enum { 115 _HF_DYNFILE_NONE = 0x0, 116 _HF_DYNFILE_INSTR_COUNT = 0x1, 117 _HF_DYNFILE_BRANCH_COUNT = 0x2, 118 _HF_DYNFILE_BTS_EDGE = 0x10, 119 _HF_DYNFILE_IPT_BLOCK = 0x20, 120 _HF_DYNFILE_SOFT = 0x40, 121 } dynFileMethod_t; 122 123 typedef struct { 124 uint64_t cpuInstrCnt; 125 uint64_t cpuBranchCnt; 126 uint64_t bbCnt; 127 uint64_t newBBCnt; 128 uint64_t softCntPc; 129 uint64_t softCntEdge; 130 uint64_t softCntCmp; 131 } hwcnt_t; 132 133 typedef enum { 134 _HF_STATE_UNSET = 0, 135 _HF_STATE_STATIC, 136 _HF_STATE_DYNAMIC_DRY_RUN, 137 _HF_STATE_DYNAMIC_MAIN, 138 _HF_STATE_DYNAMIC_MINIMIZE, 139 } fuzzState_t; 140 141 typedef enum { 142 HF_MAYBE = -1, 143 HF_NO = 0, 144 HF_YES = 1, 145 } tristate_t; 146 147 struct _dynfile_t { 148 size_t size; 149 uint64_t cov[4]; 150 size_t idx; 151 int fd; 152 uint64_t timeExecUSecs; 153 char path[PATH_MAX]; 154 struct _dynfile_t* src; 155 uint32_t refs; 156 uint8_t* data; 157 TAILQ_ENTRY(_dynfile_t) pointers; 158 }; 159 160 typedef struct _dynfile_t dynfile_t; 161 162 struct strings_t { 163 size_t len; 164 TAILQ_ENTRY(strings_t) pointers; 165 char s[]; 166 }; 167 168 typedef struct { 169 uint8_t pcGuardMap[_HF_PC_GUARD_MAX]; 170 uint8_t bbMapPc[_HF_PERF_BITMAP_SIZE_16M]; 171 uint32_t bbMapCmp[_HF_PERF_BITMAP_SIZE_16M]; 172 uint64_t pidNewPC[_HF_THREAD_MAX]; 173 uint64_t pidNewEdge[_HF_THREAD_MAX]; 174 uint64_t pidNewCmp[_HF_THREAD_MAX]; 175 uint64_t guardNb; 176 uint64_t pidTotalPC[_HF_THREAD_MAX]; 177 uint64_t pidTotalEdge[_HF_THREAD_MAX]; 178 uint64_t pidTotalCmp[_HF_THREAD_MAX]; 179 } feedback_t; 180 181 typedef struct { 182 uint32_t cnt; 183 struct { 184 uint8_t val[32]; 185 uint32_t len; 186 } valArr[1024 * 16]; 187 } cmpfeedback_t; 188 189 typedef struct { 190 struct { 191 size_t threadsMax; 192 size_t threadsFinished; 193 uint32_t threadsActiveCnt; 194 pthread_t mainThread; 195 pid_t mainPid; 196 pthread_t threads[_HF_THREAD_MAX]; 197 } threads; 198 struct { 199 const char* inputDir; 200 const char* outputDir; 201 DIR* inputDirPtr; 202 size_t fileCnt; 203 size_t testedFileCnt; 204 const char* fileExtn; 205 size_t maxFileSz; 206 size_t newUnitsAdded; 207 char workDir[PATH_MAX]; 208 const char* crashDir; 209 const char* covDirNew; 210 bool saveUnique; 211 bool saveSmaller; 212 size_t dynfileqMaxSz; 213 size_t dynfileqCnt; 214 dynfile_t* dynfileqCurrent; 215 dynfile_t* dynfileq2Current; 216 TAILQ_HEAD(dyns_t, _dynfile_t) dynfileq; 217 bool exportFeedback; 218 } io; 219 struct { 220 int argc; 221 const char* const* cmdline; 222 bool nullifyStdio; 223 bool fuzzStdin; 224 const char* externalCommand; 225 const char* postExternalCommand; 226 const char* feedbackMutateCommand; 227 bool netDriver; 228 bool persistent; 229 uint64_t asLimit; 230 uint64_t rssLimit; 231 uint64_t dataLimit; 232 uint64_t coreLimit; 233 uint64_t stackLimit; 234 bool clearEnv; 235 char* env_ptrs[128]; 236 char env_vals[128][4096]; 237 sigset_t waitSigSet; 238 } exe; 239 struct { 240 time_t timeStart; 241 time_t runEndTime; 242 time_t tmOut; 243 time_t lastCovUpdate; 244 int64_t timeOfLongestUnitUSecs; 245 bool tmoutVTALRM; 246 } timing; 247 struct { 248 struct { 249 uint8_t val[512]; 250 size_t len; 251 } dictionary[8192]; 252 size_t dictionaryCnt; 253 const char* dictionaryFile; 254 size_t mutationsMax; 255 unsigned mutationsPerRun; 256 size_t maxInputSz; 257 } mutate; 258 struct { 259 bool useScreen; 260 char cmdline_txt[65]; 261 int64_t lastDisplayUSecs; 262 } display; 263 struct { 264 bool useVerifier; 265 bool exitUponCrash; 266 uint8_t exitCodeUponCrash; 267 const char* reportFile; 268 size_t dynFileIterExpire; 269 bool only_printable; 270 bool minimize; 271 bool switchingToFDM; 272 } cfg; 273 struct { 274 bool enable; 275 bool del_report; 276 } sanitizer; 277 struct { 278 fuzzState_t state; 279 feedback_t* covFeedbackMap; 280 int covFeedbackFd; 281 cmpfeedback_t* cmpFeedbackMap; 282 int cmpFeedbackFd; 283 bool cmpFeedback; 284 const char* blocklistFile; 285 uint64_t* blocklist; 286 size_t blocklistCnt; 287 bool skipFeedbackOnTimeout; 288 uint64_t maxCov[4]; 289 dynFileMethod_t dynFileMethod; 290 hwcnt_t hwCnts; 291 } feedback; 292 struct { 293 size_t mutationsCnt; 294 size_t crashesCnt; 295 size_t uniqueCrashesCnt; 296 size_t verifiedCrashesCnt; 297 size_t blCrashesCnt; 298 size_t timeoutedCnt; 299 } cnts; 300 struct { 301 bool enabled; 302 int serverSocket; 303 int clientSocket; 304 } socketFuzzer; 305 struct { 306 pthread_rwlock_t dynfileq; 307 pthread_mutex_t feedback; 308 pthread_mutex_t report; 309 pthread_mutex_t state; 310 pthread_mutex_t input; 311 pthread_mutex_t timing; 312 } mutex; 313 314 /* For the Linux code */ 315 struct { 316 int exeFd; 317 uint64_t dynamicCutOffAddr; 318 bool disableRandomization; 319 void* ignoreAddr; 320 const char* symsBlFile; 321 char** symsBl; 322 size_t symsBlCnt; 323 const char* symsWlFile; 324 char** symsWl; 325 size_t symsWlCnt; 326 uintptr_t cloneFlags; 327 tristate_t useNetNs; 328 bool kernelOnly; 329 bool useClone; 330 } arch_linux; 331 /* For the NetBSD code */ 332 struct { 333 void* ignoreAddr; 334 const char* symsBlFile; 335 char** symsBl; 336 size_t symsBlCnt; 337 const char* symsWlFile; 338 char** symsWl; 339 size_t symsWlCnt; 340 } arch_netbsd; 341 } honggfuzz_t; 342 343 typedef enum { 344 _HF_RS_UNKNOWN = 0, 345 _HF_RS_WAITING_FOR_INITIAL_READY = 1, 346 _HF_RS_WAITING_FOR_READY = 2, 347 _HF_RS_SEND_DATA = 3, 348 } runState_t; 349 350 typedef struct { 351 honggfuzz_t* global; 352 pid_t pid; 353 int64_t timeStartedUSecs; 354 char crashFileName[PATH_MAX]; 355 uint64_t pc; 356 uint64_t backtrace; 357 uint64_t access; 358 int exception; 359 char report[_HF_REPORT_SIZE]; 360 bool mainWorker; 361 unsigned mutationsPerRun; 362 dynfile_t* dynfile; 363 bool staticFileTryMore; 364 uint32_t fuzzNo; 365 int persistentSock; 366 runState_t runState; 367 bool tmOutSignaled; 368 char* args[_HF_ARGS_MAX + 1]; 369 int perThreadCovFeedbackFd; 370 unsigned triesLeft; 371 dynfile_t* current; 372 #if !defined(_HF_ARCH_DARWIN) 373 timer_t timerId; 374 #endif // !defined(_HF_ARCH_DARWIN) 375 hwcnt_t hwCnts; 376 377 struct { 378 /* For Linux code */ 379 uint8_t* perfMmapBuf; 380 uint8_t* perfMmapAux; 381 int cpuInstrFd; 382 int cpuBranchFd; 383 int cpuIptBtsFd; 384 } arch_linux; 385 } run_t; 386 387 #endif 388