blob: bd391a2758d47ea44042fb646b1cc80357a89ddd [file] [log] [blame]
robert.swiecki3bb518c2010-10-14 00:48:24 +00001/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00002 *
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +00003 * honggfuzz - fuzzing routines
4 * -----------------------------------------
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00005 *
robert.swiecki@gmail.com8531f692015-02-17 12:25:36 +00006 * Author:
7 * Robert Swiecki <swiecki@google.com>
8 * Felix Gröbert <groebert@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00009 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000010 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000011 *
12 * Licensed under the Apache License, Version 2.0 (the "License"); you may
13 * not use this file except in compliance with the License. You may obtain
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000014 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000015 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000016 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000017 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000018 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
21 * implied. See the License for the specific language governing
22 * permissions and limitations under the License.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000023 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000024 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000025
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000026#include "common.h"
27#include "fuzz.h"
28
29#include <errno.h>
30#include <fcntl.h>
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000031#include <inttypes.h>
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +000032#include <pthread.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000033#include <signal.h>
34#include <stddef.h>
35#include <stdint.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000039#include <sys/param.h>
40#include <sys/stat.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000041#include <sys/time.h>
42#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000043#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000044#include <unistd.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000045
robert.swiecki3bb518c2010-10-14 00:48:24 +000046#include "arch.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000047#include "files.h"
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000048#include "log.h"
robert.swiecki@gmail.com36700b52015-02-22 05:03:16 +000049#include "mangle.h"
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000050#include "report.h"
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +020051#include "sanitizers.h"
Jagger00265602016-03-10 02:36:27 +010052#include "sancov.h"
Jaggerc7743512016-08-31 22:00:19 +020053#include "subproc.h"
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000054#include "util.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000055
Jagger6113c432015-09-24 05:00:28 +020056static pthread_t fuzz_mainThread;
57
robert.swiecki3bb518c2010-10-14 00:48:24 +000058static void fuzz_getFileName(honggfuzz_t * hfuzz, char *fileName)
59{
robert.swieckiba512632011-01-28 11:57:26 +000060 struct timeval tv;
61 gettimeofday(&tv, NULL);
62
Jaggerc44a89a2016-09-25 16:42:44 +020063 snprintf(fileName, PATH_MAX, "%s/.honggfuzz.%d.%lu.%" PRIx64 ".%s", hfuzz->workDir,
64 (int)getpid(), (unsigned long int)tv.tv_sec, util_rnd64(), hfuzz->fileExtn);
robert.swiecki3bb518c2010-10-14 00:48:24 +000065}
66
Robert Swieckia96d78d2016-03-14 16:50:50 +010067static bool fuzz_prepareFileDynamically(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +000068{
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010069 struct dynfile_t *dynfile;
Robert Swieckia08ab1c2016-03-14 18:29:21 +010070
71 {
Robert Swiecki76ecd5e2016-03-16 14:57:03 +010072 MX_SCOPED_LOCK(&hfuzz->dynfileq_mutex);
Robert Swiecki4b0390a2016-03-14 18:44:05 +010073
Jaggerb070b812016-03-15 05:31:30 +010074 if (hfuzz->dynfileqCnt == 0) {
Jaggere4496512016-03-16 01:55:46 +010075 LOG_F("The dynamic file corpus is empty. Apparently, the initial fuzzing of the "
76 "provided file corpus (-f) has not produced any follow-up files with positive "
77 "coverage and/or CPU counters");
Jaggerb070b812016-03-15 05:31:30 +010078 }
79
Robert Swiecki4b0390a2016-03-14 18:44:05 +010080 size_t i = 0U;
Robert Swieckia08ab1c2016-03-14 18:29:21 +010081 size_t dynFilePos = util_rndGet(0, hfuzz->dynfileqCnt - 1);
82 TAILQ_FOREACH(dynfile, &hfuzz->dynfileq, pointers) {
83 if (i++ == dynFilePos) {
84 break;
85 }
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010086 }
87 }
88
89 memcpy(fuzzer->dynamicFile, dynfile->data, dynfile->size);
Robert Swieckia08ab1c2016-03-14 18:29:21 +010090 fuzzer->dynamicFileSz = dynfile->size;
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010091
Anestis Bechtsoudis6ef24e42016-01-13 13:05:53 +020092 mangle_Resize(hfuzz, fuzzer->dynamicFile, &fuzzer->dynamicFileSz);
Robert Swieckia96d78d2016-03-14 16:50:50 +010093 mangle_mangleContent(hfuzz, fuzzer);
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +000094
Jagger1d743382016-04-02 02:09:41 +020095 if (hfuzz->persistent == false && files_writeBufToFile
robert.swiecki@gmail.com62e34ae2015-03-05 03:39:32 +000096 (fuzzer->fileName, fuzzer->dynamicFile, fuzzer->dynamicFileSz,
Jagger5a3c4c32016-04-16 19:27:47 +020097 O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC) == false) {
Robert Swieckic8c32db2015-10-09 18:06:22 +020098 LOG_E("Couldn't write buffer to file '%s'", fuzzer->fileName);
robert.swiecki@gmail.com3b6c6292015-02-26 11:48:46 +000099 return false;
100 }
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +0000101
robert.swiecki@gmail.com6d6f7562015-02-17 22:18:51 +0000102 return true;
robert.swiecki@gmail.comd7aed312015-02-03 21:26:37 +0000103}
104
robert.swiecki@gmail.com4a7a9d82015-03-01 01:25:16 +0000105static bool fuzz_prepareFile(honggfuzz_t * hfuzz, fuzzer_t * fuzzer, int rnd_index)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000106{
Robert Swieckie8f8e8d2016-10-03 23:51:32 +0200107 struct paths_t *file = files_getFileFromFileq(hfuzz, rnd_index);
108
109 ssize_t fileSz = files_readFileToBufMax(file->path, fuzzer->dynamicFile, hfuzz->maxFileSz);
Jagger1aa94d72016-04-02 02:37:35 +0200110 if (fileSz < 0) {
Robert Swieckie8f8e8d2016-10-03 23:51:32 +0200111 LOG_E("Couldn't read contents of '%s'", file->path);
robert.swiecki@gmail.combb5d2642015-02-25 20:00:00 +0000112 return false;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000113 }
Robert Swieckia96d78d2016-03-14 16:50:50 +0100114 fuzzer->dynamicFileSz = fileSz;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000115
Anestis Bechtsoudis25262b32015-11-07 22:39:47 +0200116 /* If flip rate is 0.0, early abort file mangling */
Robert Swieckia96d78d2016-03-14 16:50:50 +0100117 if (fuzzer->flipRate != 0.0L) {
118 mangle_Resize(hfuzz, fuzzer->dynamicFile, &fuzzer->dynamicFileSz);
119 mangle_mangleContent(hfuzz, fuzzer);
Anestis Bechtsoudis25262b32015-11-07 22:39:47 +0200120 }
robert.swiecki@gmail.comc070b942015-02-25 18:29:19 +0000121
Jagger1d743382016-04-02 02:09:41 +0200122 if (hfuzz->persistent == false && files_writeBufToFile
Robert Swieckia96d78d2016-03-14 16:50:50 +0100123 (fuzzer->fileName, fuzzer->dynamicFile, fuzzer->dynamicFileSz,
Jagger5a3c4c32016-04-16 19:27:47 +0200124 O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC) == false) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200125 LOG_E("Couldn't write buffer to file '%s'", fuzzer->fileName);
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +0000126 return false;
127 }
128
robert.swiecki3bb518c2010-10-14 00:48:24 +0000129 return true;
130}
131
Jaggera34b3022016-04-02 02:20:40 +0200132static bool fuzz_prepareFileExternally(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000133{
Jagger5a3c4c32016-04-16 19:27:47 +0200134 int dstfd = open(fuzzer->fileName, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0644);
Jaggera34b3022016-04-02 02:20:40 +0200135 if (dstfd == -1) {
136 PLOG_E("Couldn't create a temporary file '%s'", fuzzer->fileName);
137 return false;
Robert Swieckie48811e2016-03-09 18:31:19 +0100138 }
Jaggera34b3022016-04-02 02:20:40 +0200139 close(dstfd);
140
141 LOG_D("Created '%s' as an input file", fuzzer->fileName);
robert.swiecki3d505e22010-10-14 01:17:17 +0000142
Robert Swiecki54333cd2016-09-07 17:51:48 +0200143 const char *const argv[] = { hfuzz->externalCommand, fuzzer->fileName, NULL };
144 if (subproc_System(argv) != 0) {
145 LOG_E("Subprocess '%s' returned abnormally", hfuzz->externalCommand);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000146 return false;
147 }
Robert Swiecki54333cd2016-09-07 17:51:48 +0200148 LOG_D("Subporcess '%s' finished with success", hfuzz->externalCommand);
Jagger1d743382016-04-02 02:09:41 +0200149
150 ssize_t rsz = files_readFileToBufMax(fuzzer->fileName, fuzzer->dynamicFile, hfuzz->maxFileSz);
Jagger1aa94d72016-04-02 02:37:35 +0200151 if (rsz < 0) {
Jagger1d743382016-04-02 02:09:41 +0200152 LOG_W("Couldn't read back '%s' to the buffer", fuzzer->fileName);
153 return false;
154 }
155 fuzzer->dynamicFileSz = rsz;
156
157 if (hfuzz->persistent) {
158 unlink(fuzzer->fileName);
159 }
160
161 return true;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000162}
163
Robert Swieckiee266ac2016-10-03 02:25:59 +0200164static bool fuzz_postProcessFile(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
165{
166 if (hfuzz->persistent == true) {
167 LOG_F("Postprocessing file in persistent mode not yet supported");
168 }
169
170 const char *const argv[] = { hfuzz->postExternalCommand, fuzzer->fileName, NULL };
171 if (subproc_System(argv) != 0) {
172 LOG_E("Subprocess '%s' returned abnormally", hfuzz->postExternalCommand);
173 return false;
174 }
175 LOG_D("Subporcess '%s' finished with success", hfuzz->externalCommand);
176
177 ssize_t rsz = files_readFileToBufMax(fuzzer->fileName, fuzzer->dynamicFile, hfuzz->maxFileSz);
178 if (rsz < 0) {
179 LOG_W("Couldn't read back '%s' to the buffer", fuzzer->fileName);
180 return false;
181 }
182 fuzzer->dynamicFileSz = rsz;
183
184 return true;
185}
186
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300187static bool fuzz_runVerifier(honggfuzz_t * hfuzz, fuzzer_t * crashedFuzzer)
188{
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300189 int crashFd = -1;
190 uint8_t *crashBuf = NULL;
191 off_t crashFileSz = 0;
192
193 crashBuf = files_mapFile(crashedFuzzer->crashFileName, &crashFileSz, &crashFd, false);
194 if (crashBuf == NULL) {
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700195 LOG_E("Couldn't open and map '%s' in R/O mode", crashedFuzzer->crashFileName);
Robert Swieckie48811e2016-03-09 18:31:19 +0100196 return false;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300197 }
Jagger4fe18692016-04-22 23:15:07 +0200198 defer {
199 munmap(crashBuf, crashFileSz);
Jagger4fe18692016-04-22 23:15:07 +0200200 close(crashFd);
201 };
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300202
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700203 LOG_I("Launching verifier for %" PRIx64 " hash", crashedFuzzer->backtrace);
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300204 for (int i = 0; i < _HF_VERIFIER_ITER; i++) {
205 fuzzer_t vFuzzer = {
206 .pid = 0,
Anestis Bechtsoudis92b97042016-04-27 12:34:19 +0300207 .persistentPid = 0,
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300208 .timeStartedMillis = util_timeNowMillis(),
Anestis Bechtsoudisecb0a662015-09-27 18:19:46 +0300209 .crashFileName = {0},
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300210 .pc = 0ULL,
211 .backtrace = 0ULL,
212 .access = 0ULL,
213 .exception = 0,
214 .dynamicFileSz = 0,
215 .dynamicFile = NULL,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200216 .sanCovCnts = {
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200217 .hitBBCnt = 0ULL,
218 .totalBBCnt = 0ULL,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200219 .dsoCnt = 0ULL,
220 .iDsoCnt = 0ULL,
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200221 .newBBCnt = 0ULL,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200222 .crashesCnt = 0ULL,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200223 },
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300224 .report = {'\0'},
Jaggerb2c1fad2016-03-17 23:37:10 +0100225 .mainWorker = false,
Jaggerfa3544a2016-08-30 02:55:55 +0200226 .fuzzNo = crashedFuzzer->fuzzNo,
Jagger93253f72016-09-01 22:40:12 +0200227 .persistentSock = -1,
Robert Swiecki013bc9c2016-12-12 17:31:06 +0100228 .tmOutSignaled = false,
Jaggerb2c1fad2016-03-17 23:37:10 +0100229
Jagger2381ef42016-03-20 23:32:05 +0100230 .linux = {
231 .hwCnts = {
232 .cpuInstrCnt = 0ULL,
233 .cpuBranchCnt = 0ULL,
Jagger2381ef42016-03-20 23:32:05 +0100234 .bbCnt = 0ULL,
235 .newBBCnt = 0ULL,
Jagger34789a72016-09-08 00:36:09 +0200236 .softCntPc = 0ULL,
237 .softCntCmp = 0ULL,
Jagger2381ef42016-03-20 23:32:05 +0100238 },
239 .perfMmapBuf = NULL,
240 .perfMmapAux = NULL,
Anestis Bechtsoudis92b97042016-04-27 12:34:19 +0300241 .attachedPid = 0,
Jagger2381ef42016-03-20 23:32:05 +0100242 },
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300243 };
244
Anestis Bechtsoudis92b97042016-04-27 12:34:19 +0300245 if (arch_archThreadInit(hfuzz, &vFuzzer) == false) {
246 LOG_F("Could not initialize the thread");
247 }
248
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300249 fuzz_getFileName(hfuzz, vFuzzer.fileName);
250 if (files_writeBufToFile
Jagger33cce5d2016-04-16 20:10:36 +0200251 (vFuzzer.fileName, crashBuf, crashFileSz,
252 O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC) == false) {
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700253 LOG_E("Couldn't write buffer to file '%s'", vFuzzer.fileName);
Robert Swieckie48811e2016-03-09 18:31:19 +0100254 return false;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300255 }
256
Robert Swiecki940a0802016-11-02 12:42:09 +0100257 if (subproc_Run(hfuzz, &vFuzzer) == false) {
258 LOG_F("subproc_Run()");
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300259 }
Robert Swieckia8b8cb82016-08-17 18:27:08 +0200260
Anestis Bechtsoudis2b2a63b2016-12-28 15:34:40 +0200261 /* Delete intermediate files generated from verifier */
262 unlink(vFuzzer.fileName);
263
Anestis Bechtsoudisecb0a662015-09-27 18:19:46 +0300264 /* If stack hash doesn't match skip name tag and exit */
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300265 if (crashedFuzzer->backtrace != vFuzzer.backtrace) {
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700266 LOG_D("Verifier stack hash mismatch");
Robert Swieckie48811e2016-03-09 18:31:19 +0100267 return false;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300268 }
269 }
270
271 /* Workspace is inherited, just append a extra suffix */
272 char verFile[PATH_MAX] = { 0 };
273 snprintf(verFile, sizeof(verFile), "%s.verified", crashedFuzzer->crashFileName);
Anestis Bechtsoudisecb0a662015-09-27 18:19:46 +0300274
Anestis Bechtsoudisd86e6602015-11-07 18:34:06 +0200275 /* Copy file with new suffix & remove original copy */
276 bool dstFileExists = false;
277 if (files_copyFile(crashedFuzzer->crashFileName, verFile, &dstFileExists)) {
278 LOG_I("Successfully verified, saving as (%s)", verFile);
Jaggerd34417d2016-03-16 01:26:54 +0100279 ATOMIC_POST_INC(hfuzz->verifiedCrashesCnt);
Anestis Bechtsoudisd86e6602015-11-07 18:34:06 +0200280 unlink(crashedFuzzer->crashFileName);
281 } else {
282 if (dstFileExists) {
283 LOG_I("It seems that '%s' already exists, skipping", verFile);
284 } else {
285 LOG_E("Couldn't copy '%s' to '%s'", crashedFuzzer->crashFileName, verFile);
Robert Swieckie48811e2016-03-09 18:31:19 +0100286 return false;
Anestis Bechtsoudisd86e6602015-11-07 18:34:06 +0200287 }
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300288 }
Anestis Bechtsoudisecb0a662015-09-27 18:19:46 +0300289
Robert Swieckie48811e2016-03-09 18:31:19 +0100290 return true;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300291}
292
Jagger3c7e7ce2016-09-25 16:05:19 +0200293static fuzzState_t fuzz_getState(honggfuzz_t * hfuzz)
294{
295 return ATOMIC_GET(hfuzz->state);
296}
297
298static void fuzz_setState(honggfuzz_t * hfuzz, fuzzState_t state)
299{
300 ATOMIC_SET(hfuzz->state, state);
301}
302
Robert Swieckid258ff82016-08-29 17:54:20 +0200303static void fuzz_addFileToFileQLocked(honggfuzz_t * hfuzz, uint8_t * data, size_t size)
Robert Swieckif3534bb2016-03-14 18:55:10 +0100304{
Robert Swiecki7084e652016-03-14 19:47:00 +0100305 struct dynfile_t *dynfile = (struct dynfile_t *)util_Malloc(sizeof(struct dynfile_t));
Robert Swieckif3534bb2016-03-14 18:55:10 +0100306 dynfile->size = size;
Robert Swiecki7084e652016-03-14 19:47:00 +0100307 dynfile->data = (uint8_t *) util_Malloc(size);
Robert Swieckif3534bb2016-03-14 18:55:10 +0100308 memcpy(dynfile->data, data, size);
309 TAILQ_INSERT_TAIL(&hfuzz->dynfileq, dynfile, pointers);
310 hfuzz->dynfileqCnt++;
311
Jagger3c7e7ce2016-09-25 16:05:19 +0200312 /* No need to add new coverage if we are supposed to append new coverage-inducing inputs only */
Jagger1b2d4822016-09-25 16:19:45 +0200313 if (fuzz_getState(hfuzz) == _HF_STATE_DYNAMIC_PRE && hfuzz->covDir == NULL) {
314 LOG_D("New coverage found, but we're in the initial coverage assessment state. Skipping");
Jagger3c7e7ce2016-09-25 16:05:19 +0200315 return;
316 }
317
Jaggerb30b4812016-09-25 16:34:15 +0200318 char tmstr[512];
Jagger3968ba32016-09-25 16:44:31 +0200319 util_getLocalTime("%Y%m%d.%H%M%S", tmstr, sizeof(tmstr), time(NULL));
Robert Swieckif3534bb2016-03-14 18:55:10 +0100320 char fname[PATH_MAX];
Jagger1b2d4822016-09-25 16:19:45 +0200321 if (hfuzz->covDir == NULL) {
Jaggerb30b4812016-09-25 16:34:15 +0200322 snprintf(fname, sizeof(fname), "%s/TIME.%s.ITER.%" PRIu64 ".RND.%" PRIx64 ".HONGGFUZZ.COV",
Jaggerc44a89a2016-09-25 16:42:44 +0200323 hfuzz->inputDir, tmstr, (uint64_t) ATOMIC_GET(hfuzz->mutationsCnt), util_rnd64());
Jagger3c7e7ce2016-09-25 16:05:19 +0200324 } else {
Jaggerb30b4812016-09-25 16:34:15 +0200325 snprintf(fname, sizeof(fname), "%s/TIME.%s.ITER.%" PRIu64 ".RND.%" PRIx64 ".HONGGFUZZ.COV",
Jaggerc44a89a2016-09-25 16:42:44 +0200326 hfuzz->covDir, tmstr, (uint64_t) ATOMIC_GET(hfuzz->mutationsCnt), util_rnd64());
Jagger3c7e7ce2016-09-25 16:05:19 +0200327 }
328
Jagger33cce5d2016-04-16 20:10:36 +0200329 if (files_writeBufToFile(fname, data, size, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC)
330 == false) {
Robert Swieckif3534bb2016-03-14 18:55:10 +0100331 LOG_W("Couldn't write buffer to file '%s'", fname);
332 }
333}
334
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200335static void fuzz_perfFeedback(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
336{
337 LOG_D
Jagger395df022016-08-21 01:13:25 +0200338 ("New file size: %zu, Perf feedback new/cur (instr,branch): %" PRIu64 "/%" PRIu64 "/%"
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100339 PRIu64 "/%" PRIu64 ", BBcnt new/total: %" PRIu64 "/%" PRIu64, fuzzer->dynamicFileSz,
Jagger247c3b42016-03-21 23:24:05 +0100340 fuzzer->linux.hwCnts.cpuInstrCnt, hfuzz->linux.hwCnts.cpuInstrCnt,
341 fuzzer->linux.hwCnts.cpuBranchCnt, hfuzz->linux.hwCnts.cpuBranchCnt,
342 fuzzer->linux.hwCnts.newBBCnt, hfuzz->linux.hwCnts.bbCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200343
Robert Swiecki76ecd5e2016-03-16 14:57:03 +0100344 MX_SCOPED_LOCK(&hfuzz->dynfileq_mutex);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200345
Jagger34789a72016-09-08 00:36:09 +0200346 uint64_t softCntPc = 0UL;
347 uint64_t softCntCmp = 0UL;
Jagger251d0192016-08-24 00:54:04 +0200348 if (hfuzz->bbFd != -1) {
Jagger34789a72016-09-08 00:36:09 +0200349 softCntPc = ATOMIC_GET(hfuzz->feedback->pidFeedbackPc[fuzzer->fuzzNo]);
350 ATOMIC_CLEAR(hfuzz->feedback->pidFeedbackPc[fuzzer->fuzzNo]);
351 softCntCmp = ATOMIC_GET(hfuzz->feedback->pidFeedbackCmp[fuzzer->fuzzNo]);
352 ATOMIC_CLEAR(hfuzz->feedback->pidFeedbackCmp[fuzzer->fuzzNo]);
Jagger251d0192016-08-24 00:54:04 +0200353 }
Jaggerb01aaae2016-08-20 03:35:38 +0200354
Jagger302c2ea2016-09-07 03:54:43 +0200355 int64_t diff0 = hfuzz->linux.hwCnts.cpuInstrCnt - fuzzer->linux.hwCnts.cpuInstrCnt;
356 int64_t diff1 = hfuzz->linux.hwCnts.cpuBranchCnt - fuzzer->linux.hwCnts.cpuBranchCnt;
Jagger302c2ea2016-09-07 03:54:43 +0200357
Jagger8d0002c2016-08-17 03:44:23 +0200358 /*
359 * Coverage is the primary counter, the rest is secondary, and taken into consideration only
360 * if the coverage counter has not been changed
361 */
Jagger34789a72016-09-08 00:36:09 +0200362 if (fuzzer->linux.hwCnts.newBBCnt > 0 || softCntPc > 0 || softCntCmp > 0 || diff0 < 0
Robert Swieckid158aac2016-11-01 23:14:12 +0100363 || diff1 < 0) {
Robert Swiecki92ec8d22016-11-21 01:10:18 +0100364
365 if (diff0 < 0) {
366 hfuzz->linux.hwCnts.cpuInstrCnt = fuzzer->linux.hwCnts.cpuInstrCnt;
367 }
368 if (diff1 < 0) {
369 hfuzz->linux.hwCnts.cpuBranchCnt = fuzzer->linux.hwCnts.cpuBranchCnt;
370 }
Jagger247c3b42016-03-21 23:24:05 +0100371 hfuzz->linux.hwCnts.bbCnt += fuzzer->linux.hwCnts.newBBCnt;
Jagger34789a72016-09-08 00:36:09 +0200372 hfuzz->linux.hwCnts.softCntPc += softCntPc;
373 hfuzz->linux.hwCnts.softCntCmp += softCntCmp;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200374
Jagger395df022016-08-21 01:13:25 +0200375 LOG_I
Robert Swieckid158aac2016-11-01 23:14:12 +0100376 ("New: %zu B., (instr,branch,soft,soft-cmp,perf): %" PRIu64 "/%"
377 PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64 ", Total: %" PRIu64
Jagger91c687c2016-09-07 03:51:21 +0200378 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64, fuzzer->dynamicFileSz,
Jagger34789a72016-09-08 00:36:09 +0200379 fuzzer->linux.hwCnts.cpuInstrCnt, fuzzer->linux.hwCnts.cpuBranchCnt, softCntPc,
Robert Swieckid158aac2016-11-01 23:14:12 +0100380 softCntCmp, fuzzer->linux.hwCnts.newBBCnt,
Jagger91c687c2016-09-07 03:51:21 +0200381 hfuzz->linux.hwCnts.cpuInstrCnt, hfuzz->linux.hwCnts.cpuBranchCnt,
Jagger34789a72016-09-08 00:36:09 +0200382 hfuzz->linux.hwCnts.softCntPc, hfuzz->linux.hwCnts.softCntCmp,
Robert Swieckid158aac2016-11-01 23:14:12 +0100383 hfuzz->linux.hwCnts.bbCnt);
Jagger395df022016-08-21 01:13:25 +0200384
Robert Swieckid258ff82016-08-29 17:54:20 +0200385 fuzz_addFileToFileQLocked(hfuzz, fuzzer->dynamicFile, fuzzer->dynamicFileSz);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200386 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200387}
388
389static void fuzz_sanCovFeedback(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
390{
391 LOG_D
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100392 ("File size (Best/New): %zu, SanCov feedback (bb,dso): Best: [%" PRIu64
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200393 ",%" PRIu64 "] / New: [%" PRIu64 ",%" PRIu64 "], newBBs:%" PRIu64,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100394 fuzzer->dynamicFileSz, hfuzz->sanCovCnts.hitBBCnt,
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200395 hfuzz->sanCovCnts.iDsoCnt, fuzzer->sanCovCnts.hitBBCnt, fuzzer->sanCovCnts.iDsoCnt,
396 fuzzer->sanCovCnts.newBBCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200397
Robert Swiecki76ecd5e2016-03-16 14:57:03 +0100398 MX_SCOPED_LOCK(&hfuzz->dynfileq_mutex);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200399
Jaggerd5738372016-08-17 20:12:15 +0200400 int64_t diff0 = hfuzz->linux.hwCnts.cpuInstrCnt - fuzzer->linux.hwCnts.cpuInstrCnt;
401 int64_t diff1 = hfuzz->linux.hwCnts.cpuBranchCnt - fuzzer->linux.hwCnts.cpuBranchCnt;
Jaggerd5738372016-08-17 20:12:15 +0200402
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200403 /*
404 * Keep mutated seed if:
Robert Swiecki142f9412016-03-14 19:22:01 +0100405 * a) Newly discovered (not met before) BBs
406 * b) More instrumented DSOs loaded
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100407 *
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200408 * TODO: (a) method can significantly assist to further improvements in interesting areas
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200409 * discovery if combined with seeds pool/queue support. If a runtime queue is maintained
410 * more interesting seeds can be saved between runs instead of instantly discarded
411 * based on current absolute elitism (only one mutated seed is promoted).
412 */
Jaggerd5738372016-08-17 20:12:15 +0200413
414 bool newCov = (fuzzer->sanCovCnts.newBBCnt > 0
415 || hfuzz->sanCovCnts.iDsoCnt < fuzzer->sanCovCnts.iDsoCnt);
416
Robert Swieckid158aac2016-11-01 23:14:12 +0100417 if (newCov || (diff0 < 0 || diff1 < 0)) {
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100418 LOG_I("SanCov Update: file size (Cur): %zu, newBBs:%" PRIu64
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200419 ", counters (Cur,New): %" PRIu64 "/%" PRIu64 ",%" PRIu64 "/%" PRIu64,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100420 fuzzer->dynamicFileSz, fuzzer->sanCovCnts.newBBCnt,
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200421 hfuzz->sanCovCnts.hitBBCnt, hfuzz->sanCovCnts.iDsoCnt, fuzzer->sanCovCnts.hitBBCnt,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200422 fuzzer->sanCovCnts.iDsoCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200423
Robert Swiecki142f9412016-03-14 19:22:01 +0100424 hfuzz->sanCovCnts.hitBBCnt += fuzzer->sanCovCnts.newBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200425 hfuzz->sanCovCnts.dsoCnt = fuzzer->sanCovCnts.dsoCnt;
426 hfuzz->sanCovCnts.iDsoCnt = fuzzer->sanCovCnts.iDsoCnt;
427 hfuzz->sanCovCnts.crashesCnt += fuzzer->sanCovCnts.crashesCnt;
Robert Swiecki142f9412016-03-14 19:22:01 +0100428 hfuzz->sanCovCnts.newBBCnt = fuzzer->sanCovCnts.newBBCnt;
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200429
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200430 if (hfuzz->sanCovCnts.totalBBCnt < fuzzer->sanCovCnts.totalBBCnt) {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200431 /* Keep only the max value (for dlopen cases) to measure total target coverage */
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200432 hfuzz->sanCovCnts.totalBBCnt = fuzzer->sanCovCnts.totalBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200433 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200434
Jaggerd5738372016-08-17 20:12:15 +0200435 hfuzz->linux.hwCnts.cpuInstrCnt = fuzzer->linux.hwCnts.cpuInstrCnt;
436 hfuzz->linux.hwCnts.cpuBranchCnt = fuzzer->linux.hwCnts.cpuBranchCnt;
Jaggerd5738372016-08-17 20:12:15 +0200437
Robert Swieckid258ff82016-08-29 17:54:20 +0200438 fuzz_addFileToFileQLocked(hfuzz, fuzzer->dynamicFile, fuzzer->dynamicFileSz);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200439 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200440}
441
Robert Swieckidecf14b2016-03-31 15:09:28 +0200442static void fuzz_fuzzLoop(honggfuzz_t * hfuzz, fuzzer_t * fuzzer)
Jagger190f0dc2015-09-05 16:41:22 +0200443{
Robert Swieckidecf14b2016-03-31 15:09:28 +0200444 fuzzer->pid = 0;
445 fuzzer->timeStartedMillis = util_timeNowMillis();
446 fuzzer->crashFileName[0] = '\0';
447 fuzzer->pc = 0ULL;
448 fuzzer->backtrace = 0ULL;
449 fuzzer->access = 0ULL;
450 fuzzer->exception = 0;
451 fuzzer->report[0] = '\0';
452 fuzzer->mainWorker = true;
453 fuzzer->origFileName = "DYNAMIC";
454 fuzzer->flipRate = hfuzz->origFlipRate;
455 fuzzer->dynamicFileSz = 0;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100456
Robert Swieckidecf14b2016-03-31 15:09:28 +0200457 fuzzer->sanCovCnts.hitBBCnt = 0ULL;
458 fuzzer->sanCovCnts.totalBBCnt = 0ULL;
459 fuzzer->sanCovCnts.dsoCnt = 0ULL;
460 fuzzer->sanCovCnts.newBBCnt = 0ULL;
461 fuzzer->sanCovCnts.crashesCnt = 0ULL;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100462
Robert Swieckidecf14b2016-03-31 15:09:28 +0200463 fuzzer->linux.hwCnts.cpuInstrCnt = 0ULL;
464 fuzzer->linux.hwCnts.cpuBranchCnt = 0ULL;
Robert Swieckidecf14b2016-03-31 15:09:28 +0200465 fuzzer->linux.hwCnts.bbCnt = 0ULL;
466 fuzzer->linux.hwCnts.newBBCnt = 0ULL;
467 fuzzer->linux.perfMmapBuf = NULL;
468 fuzzer->linux.perfMmapAux = NULL;
Jagger190f0dc2015-09-05 16:41:22 +0200469
Anestis Bechtsoudis2013f252015-11-07 22:03:31 +0200470 size_t rnd_index = util_rndGet(0, hfuzz->fileCnt - 1);
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200471
472 /* If dry run mode, pick the next file and not a random one */
Robert Swieckidecf14b2016-03-31 15:09:28 +0200473 if (fuzzer->flipRate == 0.0L && hfuzz->useVerifier) {
Jaggerd34417d2016-03-16 01:26:54 +0100474 rnd_index = ATOMIC_POST_INC(hfuzz->lastFileIndex);
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200475 }
Robert Swiecki129afe82016-03-15 20:03:20 +0100476
Robert Swiecki6d01e822016-03-15 20:21:46 +0100477 if (fuzz_getState(hfuzz) == _HF_STATE_DYNAMIC_PRE) {
Jaggerd34417d2016-03-16 01:26:54 +0100478 rnd_index = ATOMIC_POST_INC(hfuzz->lastFileIndex);
Robert Swieckia96d78d2016-03-14 16:50:50 +0100479 if (rnd_index >= hfuzz->fileCnt) {
Jagger33fd9522016-03-15 22:13:57 +0100480 /*
481 * The waiting logic (for the DYNAMIC_PRE phase to finish) should be based on cond-waits
482 * or mutexes, but it'd complicate code too much
483 */
Robert Swiecki6d01e822016-03-15 20:21:46 +0100484 while (fuzz_getState(hfuzz) == _HF_STATE_DYNAMIC_PRE) {
485 sleep(1);
Robert Swiecki129afe82016-03-15 20:03:20 +0100486 }
Robert Swieckia96d78d2016-03-14 16:50:50 +0100487 }
488 }
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200489
Jagger33fd9522016-03-15 22:13:57 +0100490 fuzzState_t state = fuzz_getState(hfuzz);
Robert Swieckidecf14b2016-03-31 15:09:28 +0200491 if (state != _HF_STATE_DYNAMIC_MAIN) {
Robert Swieckie8f8e8d2016-10-03 23:51:32 +0200492 fuzzer->origFileName = files_basename(files_getFileFromFileq(hfuzz, rnd_index)->path);
Robert Swieckia08ab1c2016-03-14 18:29:21 +0100493 }
Robert Swiecki6d01e822016-03-15 20:21:46 +0100494
Robert Swieckidecf14b2016-03-31 15:09:28 +0200495 fuzz_getFileName(hfuzz, fuzzer->fileName);
Jagger190f0dc2015-09-05 16:41:22 +0200496
Robert Swieckiee266ac2016-10-03 02:25:59 +0200497 if (state == _HF_STATE_DYNAMIC_PRE) {
498 fuzzer->flipRate = 0.0f;
499 if (!fuzz_prepareFile(hfuzz, fuzzer, rnd_index)) {
500 LOG_F("fuzz_prepareFile() failed");
501 }
502 } else if (hfuzz->externalCommand) {
Jagger30384ec2016-04-02 02:30:32 +0200503 if (!fuzz_prepareFileExternally(hfuzz, fuzzer)) {
504 LOG_F("fuzz_prepareFileExternally() failed");
505 }
506 } else if (state == _HF_STATE_DYNAMIC_MAIN) {
Robert Swieckidecf14b2016-03-31 15:09:28 +0200507 if (!fuzz_prepareFileDynamically(hfuzz, fuzzer)) {
Jagger1d8e0c62016-04-02 02:22:40 +0200508 LOG_F("fuzz_prepareFileDynamically() failed");
Robert Swieckia96d78d2016-03-14 16:50:50 +0100509 }
Jagger190f0dc2015-09-05 16:41:22 +0200510 } else {
Robert Swieckidecf14b2016-03-31 15:09:28 +0200511 if (!fuzz_prepareFile(hfuzz, fuzzer, rnd_index)) {
Jagger1d8e0c62016-04-02 02:22:40 +0200512 LOG_F("fuzz_prepareFile() failed");
Jagger190f0dc2015-09-05 16:41:22 +0200513 }
514 }
515
Robert Swiecki0fcace22016-10-03 21:24:32 +0200516 if (state == _HF_STATE_STATIC && hfuzz->postExternalCommand != NULL) {
Robert Swieckiee266ac2016-10-03 02:25:59 +0200517 if (!fuzz_postProcessFile(hfuzz, fuzzer)) {
518 LOG_F("fuzz_postProcessFile() failed");
519 }
520 }
521
Robert Swiecki940a0802016-11-02 12:42:09 +0100522 if (subproc_Run(hfuzz, fuzzer) == false) {
523 LOG_F("subproc_Run()");
Jagger190f0dc2015-09-05 16:41:22 +0200524 }
525
Jaggera34b3022016-04-02 02:20:40 +0200526 if (hfuzz->persistent == false) {
527 unlink(fuzzer->fileName);
528 }
Jagger190f0dc2015-09-05 16:41:22 +0200529
530 if (hfuzz->dynFileMethod != _HF_DYNFILE_NONE) {
Robert Swieckidecf14b2016-03-31 15:09:28 +0200531 fuzz_perfFeedback(hfuzz, fuzzer);
Jaggerabb6ae02016-03-18 01:55:51 +0100532 }
533 if (hfuzz->useSanCov) {
Robert Swieckidecf14b2016-03-31 15:09:28 +0200534 fuzz_sanCovFeedback(hfuzz, fuzzer);
Robert Swiecki0f937af2016-03-30 18:19:16 +0200535 }
Jagger190f0dc2015-09-05 16:41:22 +0200536
Robert Swieckidecf14b2016-03-31 15:09:28 +0200537 if (hfuzz->useVerifier && (fuzzer->crashFileName[0] != 0) && fuzzer->backtrace) {
538 if (!fuzz_runVerifier(hfuzz, fuzzer)) {
539 LOG_I("Failed to verify %s", fuzzer->crashFileName);
Anestis Bechtsoudis3085f222015-09-27 18:35:26 +0300540 }
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300541 }
542
Robert Swiecki216fef62016-10-20 18:32:58 +0200543 report_Report(hfuzz, fuzzer->report);
Robert Swiecki05354ca2016-03-15 19:10:23 +0100544
Jaggerd34417d2016-03-16 01:26:54 +0100545 if (state == _HF_STATE_DYNAMIC_PRE && ATOMIC_PRE_INC(hfuzz->doneFileIndex) >= hfuzz->fileCnt) {
Robert Swiecki6d01e822016-03-15 20:21:46 +0100546 fuzz_setState(hfuzz, _HF_STATE_DYNAMIC_MAIN);
Robert Swiecki05354ca2016-03-15 19:10:23 +0100547 }
Jagger190f0dc2015-09-05 16:41:22 +0200548}
549
Jaggerfa3544a2016-08-30 02:55:55 +0200550static uint32_t fuzz_threadNo = 0;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000551static void *fuzz_threadNew(void *arg)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000552{
Jaggerfa3544a2016-08-30 02:55:55 +0200553 unsigned int fuzzNo = ATOMIC_POST_INC(fuzz_threadNo);
554
555 LOG_I("Launched new fuzzing thread, no. #%" PRId32, fuzzNo);
Robert Swiecki0e673882016-03-31 18:50:29 +0200556
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000557 honggfuzz_t *hfuzz = (honggfuzz_t *) arg;
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200558
Robert Swieckidecf14b2016-03-31 15:09:28 +0200559 fuzzer_t fuzzer = {
560 .pid = 0,
561 .persistentPid = 0,
562 .dynamicFile = util_Malloc(hfuzz->maxFileSz),
Jaggerfa3544a2016-08-30 02:55:55 +0200563 .fuzzNo = fuzzNo,
Jagger93253f72016-09-01 22:40:12 +0200564 .persistentSock = -1,
Robert Swiecki013bc9c2016-12-12 17:31:06 +0100565 .tmOutSignaled = false,
Robert Swiecki12800cd2016-03-31 15:38:10 +0200566
Robert Swieckib692f282016-08-25 16:21:08 +0200567 .linux.attachedPid = 0,
Robert Swieckidecf14b2016-03-31 15:09:28 +0200568 };
Jagger4fe18692016-04-22 23:15:07 +0200569 defer {
570 free(fuzzer.dynamicFile);
571 };
Robert Swieckidecf14b2016-03-31 15:09:28 +0200572
573 if (arch_archThreadInit(hfuzz, &fuzzer) == false) {
Robert Swiecki0f937af2016-03-30 18:19:16 +0200574 LOG_F("Could not initialize the thread");
575 }
576
Robert Swieckia96d78d2016-03-14 16:50:50 +0100577 for (;;) {
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200578 /* Check if dry run mode with verifier enabled */
Robert Swieckia96d78d2016-03-14 16:50:50 +0100579 if (hfuzz->origFlipRate == 0.0L && hfuzz->useVerifier) {
Jaggerd34417d2016-03-16 01:26:54 +0100580 if (ATOMIC_POST_INC(hfuzz->mutationsCnt) >= hfuzz->fileCnt) {
581 ATOMIC_POST_INC(hfuzz->threadsFinished);
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200582 // All files checked, weak-up the main process
583 pthread_kill(fuzz_mainThread, SIGALRM);
584 return NULL;
585 }
586 }
587 /* Check for max iterations limit if set */
Jaggerd34417d2016-03-16 01:26:54 +0100588 else if ((ATOMIC_POST_INC(hfuzz->mutationsCnt) >= hfuzz->mutationsMax)
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200589 && hfuzz->mutationsMax) {
Jaggerd34417d2016-03-16 01:26:54 +0100590 ATOMIC_POST_INC(hfuzz->threadsFinished);
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200591 // Wake-up the main process
Jagger6113c432015-09-24 05:00:28 +0200592 pthread_kill(fuzz_mainThread, SIGALRM);
Jaggerea39a8f2015-09-05 00:57:22 +0200593 return NULL;
594 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000595
Robert Swieckidecf14b2016-03-31 15:09:28 +0200596 fuzz_fuzzLoop(hfuzz, &fuzzer);
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000597 }
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000598}
599
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000600static void fuzz_runThread(honggfuzz_t * hfuzz, void *(*thread) (void *))
601{
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000602 pthread_attr_t attr;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000603
robert.swiecki@gmail.com6f5c2392015-02-16 18:13:09 +0000604 pthread_attr_init(&attr);
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000605 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
robert.swiecki@gmail.com441089a2015-02-23 13:14:07 +0000606 pthread_attr_setstacksize(&attr, _HF_PTHREAD_STACKSIZE);
robert.swiecki@gmail.com011981f2015-02-17 19:06:44 +0000607 pthread_attr_setguardsize(&attr, (size_t) sysconf(_SC_PAGESIZE));
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000608
robert.swiecki@gmail.com01b6dd42015-02-16 18:11:28 +0000609 pthread_t t;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000610 if (pthread_create(&t, &attr, thread, (void *)hfuzz) < 0) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200611 PLOG_F("Couldn't create a new thread");
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000612 }
613
614 return;
615}
616
Jagger08816fd2016-03-11 01:32:38 +0100617void fuzz_threads(honggfuzz_t * hfuzz)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000618{
Jagger6113c432015-09-24 05:00:28 +0200619 fuzz_mainThread = pthread_self();
620
robert.swiecki@gmail.com956276a2015-04-16 16:51:52 +0000621 if (!arch_archInit(hfuzz)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200622 LOG_F("Couldn't prepare arch for fuzzing");
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000623 }
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200624 if (!sanitizers_Init(hfuzz)) {
625 LOG_F("Couldn't prepare sanitizer options");
626 }
Jagger00265602016-03-10 02:36:27 +0100627 if (!sancov_Init(hfuzz)) {
628 LOG_F("Couldn't prepare sancov options");
629 }
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000630
Robert Swieckia96d78d2016-03-14 16:50:50 +0100631 if (hfuzz->useSanCov || hfuzz->dynFileMethod != _HF_DYNFILE_NONE) {
Jaggerebe19292016-03-17 00:11:44 +0100632 fuzz_setState(hfuzz, _HF_STATE_DYNAMIC_PRE);
Robert Swieckia96d78d2016-03-14 16:50:50 +0100633 } else {
Jaggerebe19292016-03-17 00:11:44 +0100634 fuzz_setState(hfuzz, _HF_STATE_STATIC);
Robert Swieckia96d78d2016-03-14 16:50:50 +0100635 }
636
Jaggerea39a8f2015-09-05 00:57:22 +0200637 for (size_t i = 0; i < hfuzz->threadsMax; i++) {
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000638 fuzz_runThread(hfuzz, fuzz_threadNew);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000639 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000640}