blob: a250e6d5d07b936764b8547fa3e1e5980b45703a [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 Swiecki46288f72018-02-27 17:28:47 +01006 * Authors: Robert Swiecki <swiecki@google.com>
7 * Felix Gröbert <groebert@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00008 *
Robert Swiecki46288f72018-02-27 17:28:47 +01009 * Copyright 2010-2018 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000010 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License. You may obtain
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000013 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000014 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000015 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000016 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000017 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
20 * implied. See the License for the specific language governing
21 * permissions and limitations under the License.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000022 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000023 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000024
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000025#include "fuzz.h"
26
27#include <errno.h>
28#include <fcntl.h>
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000029#include <inttypes.h>
Robert Swiecki2af83ec2017-06-05 23:54:22 +020030#include <libgen.h>
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +000031#include <pthread.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000032#include <signal.h>
33#include <stddef.h>
34#include <stdint.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
Robert Swiecki10eeb0a2017-09-28 15:42:52 +020038#include <sys/mman.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 Swieckid0fa62c2017-09-28 18:11:05 +020046#include "arch.h"
47#include "honggfuzz.h"
48#include "input.h"
Robert Swiecki246af3e2018-01-05 14:56:32 +010049#include "libhfcommon/common.h"
50#include "libhfcommon/files.h"
51#include "libhfcommon/log.h"
52#include "libhfcommon/util.h"
robert.swiecki@gmail.com36700b52015-02-22 05:03:16 +000053#include "mangle.h"
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000054#include "report.h"
Robert Swieckiec7b8452017-06-01 13:25:56 +020055#include "sancov.h"
56#include "sanitizers.h"
dobinedf9f8d2018-01-21 13:57:02 +010057#include "socketfuzzer.h"
Robert Swiecki56276192018-01-21 15:43:02 +010058#include "subproc.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000059
Robert Swiecki0dde76d2017-11-16 19:25:44 +010060static time_t termTimeStamp = 0;
61
62bool fuzz_isTerminating(void) {
63 if (ATOMIC_GET(termTimeStamp) != 0) {
Robert Swiecki35978ac2017-11-16 18:00:53 +010064 return true;
65 }
66 return false;
67}
68
Robert Swiecki0dde76d2017-11-16 19:25:44 +010069void fuzz_setTerminating(void) {
70 if (ATOMIC_GET(termTimeStamp) != 0) {
Robert Swiecki35978ac2017-11-16 18:00:53 +010071 return;
72 }
Robert Swiecki0dde76d2017-11-16 19:25:44 +010073 ATOMIC_SET(termTimeStamp, time(NULL));
74}
75
76bool fuzz_shouldTerminate() {
77 if (ATOMIC_GET(termTimeStamp) == 0) {
78 return false;
79 }
80 if ((time(NULL) - ATOMIC_GET(termTimeStamp)) > 5) {
81 return true;
82 }
83 return false;
Robert Swiecki35978ac2017-11-16 18:00:53 +010084}
85
Robert Swieckifb8a5b62018-01-14 05:16:59 +010086static fuzzState_t fuzz_getState(honggfuzz_t* hfuzz) {
Robert Swiecki363510f2018-03-09 02:00:30 +010087 return ATOMIC_GET(hfuzz->feedback.state);
Robert Swieckia7841da2017-02-24 17:27:06 +010088}
89
Robert Swieckiced3eba2017-12-15 15:33:03 +010090static bool fuzz_writeCovFile(const char* dir, const uint8_t* data, size_t len) {
91 char fname[PATH_MAX];
92
93 uint64_t crc64f = util_CRC64(data, len);
94 uint64_t crc64r = util_CRC64Rev(data, len);
95 snprintf(fname, sizeof(fname), "%s/%016" PRIx64 "%016" PRIx64 ".%08" PRIx32 ".honggfuzz.cov",
96 dir, crc64f, crc64r, (uint32_t)len);
97
Robert Swieckifff99812018-01-12 02:23:42 +010098 if (files_exists(fname)) {
Robert Swieckiced3eba2017-12-15 15:33:03 +010099 LOG_D("File '%s' already exists in the output corpus directory '%s'", fname, dir);
100 return true;
101 }
102
103 LOG_D("Adding file '%s' to the corpus directory '%s'", fname, dir);
104
Robert Swieckifff99812018-01-12 02:23:42 +0100105 if (!files_writeBufToFile(fname, data, len, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC)) {
Robert Swieckiced3eba2017-12-15 15:33:03 +0100106 LOG_W("Couldn't write buffer to file '%s'", fname);
107 return false;
108 }
109
110 return true;
111}
112
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100113static void fuzz_addFileToFileQ(honggfuzz_t* hfuzz, const uint8_t* data, size_t len) {
Robert Swiecki36f7e512018-01-16 03:46:41 +0100114 ATOMIC_SET(hfuzz->timing.lastCovUpdate, time(NULL));
115
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200116 struct dynfile_t* dynfile = (struct dynfile_t*)util_Malloc(sizeof(struct dynfile_t));
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100117 dynfile->size = len;
118 dynfile->data = (uint8_t*)util_Malloc(len);
119 memcpy(dynfile->data, data, len);
Robert Swiecki37498fd2017-03-12 21:12:54 +0100120
Robert Swiecki363510f2018-03-09 02:00:30 +0100121 MX_SCOPED_RWLOCK_WRITE(&hfuzz->io.dynfileq_mutex);
122 TAILQ_INSERT_TAIL(&hfuzz->io.dynfileq, dynfile, pointers);
123 hfuzz->io.dynfileqCnt++;
Robert Swieckif3534bb2016-03-14 18:55:10 +0100124
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100125 if (hfuzz->socketFuzzer.enabled) {
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100126 /* Don't add coverage data to files in socketFuzzer mode */
dobinedf9f8d2018-01-21 13:57:02 +0100127 return;
128 }
129
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100130 if (!fuzz_writeCovFile(hfuzz->io.covDirAll, data, len)) {
131 LOG_E("Couldn't save the coverage data to '%s'", hfuzz->io.covDirAll);
Robert Swieckiced3eba2017-12-15 15:33:03 +0100132 }
133
134 /* No need to add files to the new coverage dir, if this is just the dry-run phase */
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100135 if (fuzz_getState(hfuzz) == _HF_STATE_DYNAMIC_DRY_RUN || hfuzz->io.covDirNew == NULL) {
Jagger3c7e7ce2016-09-25 16:05:19 +0200136 return;
137 }
138
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100139 if (!fuzz_writeCovFile(hfuzz->io.covDirNew, data, len)) {
140 LOG_E("Couldn't save the new coverage data to '%s'", hfuzz->io.covDirNew);
141 }
142}
143
144static void fuzz_setDynamicMainState(run_t* run) {
145 /* All threads need to indicate willingness to switch to the DYNAMIC_MAIN state. Count them! */
146 static uint32_t cnt = 0;
147 ATOMIC_PRE_INC(cnt);
148
149 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
150 MX_SCOPED_LOCK(&state_mutex);
151
152 if (fuzz_getState(run->global) == _HF_STATE_DYNAMIC_MAIN) {
153 return;
154 }
155
156 for (;;) {
157 /* Check if all threads have already reported in for changing state */
158 if (ATOMIC_GET(cnt) == run->global->threads.threadsMax) {
159 break;
160 }
161 if (fuzz_isTerminating()) {
162 return;
163 }
164 usleep(1000 * 10); /* Check every 10ms */
165 }
166
167 LOG_I("Entering phase 2/2: Dynamic Main");
Robert Swiecki94d314c2018-02-07 21:23:00 +0100168 snprintf(run->origFileName, sizeof(run->origFileName), "[DYNAMIC]");
Robert Swiecki363510f2018-03-09 02:00:30 +0100169 ATOMIC_SET(run->global->feedback.state, _HF_STATE_DYNAMIC_MAIN);
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100170
171 /*
172 * If the initial fuzzing yielded no useful coverage, just add a single 1-byte file to the
173 * dynamic corpus, so the dynamic phase doesn't fail because of lack of useful inputs
174 */
Robert Swiecki363510f2018-03-09 02:00:30 +0100175 if (run->global->io.dynfileqCnt == 0) {
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100176 fuzz_addFileToFileQ(run->global, (const uint8_t*)"\0", 1U);
Robert Swieckif3534bb2016-03-14 18:55:10 +0100177 }
178}
179
Robert Swieckid50ed422017-11-13 23:32:26 +0100180static void fuzz_perfFeedback(run_t* run) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100181 if (run->global->feedback.skipFeedbackOnTimeout && run->tmOutSignaled) {
Robert Swiecki53ec9e42017-02-15 20:34:27 +0100182 return;
183 }
184
Robert Swiecki0b566112017-10-17 17:39:07 +0200185 LOG_D("New file size: %zu, Perf feedback new/cur (instr,branch): %" PRIu64 "/%" PRIu64
186 "/%" PRIu64 "/%" PRIu64 ", BBcnt new/total: %" PRIu64 "/%" PRIu64,
Robert Swiecki78633d12017-11-13 23:24:55 +0100187 run->dynamicFileSz, run->linux.hwCnts.cpuInstrCnt, run->global->linux.hwCnts.cpuInstrCnt,
188 run->linux.hwCnts.cpuBranchCnt, run->global->linux.hwCnts.cpuBranchCnt,
189 run->linux.hwCnts.newBBCnt, run->global->linux.hwCnts.bbCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200190
Robert Swieckia5b918a2018-03-07 23:59:53 +0100191 MX_SCOPED_LOCK(&run->global->feedback.feedback_mutex);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200192
Robert Swieckif2da05a2018-01-12 03:01:09 +0100193 uint64_t softCntPc = 0;
194 uint64_t softCntEdge = 0;
195 uint64_t softCntCmp = 0;
Robert Swieckia5b918a2018-03-07 23:59:53 +0100196 if (run->global->feedback.bbFd != -1) {
197 softCntPc = ATOMIC_GET(run->global->feedback.feedbackMap->pidFeedbackPc[run->fuzzNo]);
198 ATOMIC_CLEAR(run->global->feedback.feedbackMap->pidFeedbackPc[run->fuzzNo]);
199 softCntEdge = ATOMIC_GET(run->global->feedback.feedbackMap->pidFeedbackEdge[run->fuzzNo]);
200 ATOMIC_CLEAR(run->global->feedback.feedbackMap->pidFeedbackEdge[run->fuzzNo]);
201 softCntCmp = ATOMIC_GET(run->global->feedback.feedbackMap->pidFeedbackCmp[run->fuzzNo]);
202 ATOMIC_CLEAR(run->global->feedback.feedbackMap->pidFeedbackCmp[run->fuzzNo]);
Jagger251d0192016-08-24 00:54:04 +0200203 }
Jaggerb01aaae2016-08-20 03:35:38 +0200204
Robert Swiecki78633d12017-11-13 23:24:55 +0100205 int64_t diff0 = run->global->linux.hwCnts.cpuInstrCnt - run->linux.hwCnts.cpuInstrCnt;
206 int64_t diff1 = run->global->linux.hwCnts.cpuBranchCnt - run->linux.hwCnts.cpuBranchCnt;
Jagger302c2ea2016-09-07 03:54:43 +0200207
Robert Swiecki7b19fe52018-01-12 03:56:42 +0100208 /* Any increase in coverage (edge, pc, cmp, hw) counters forces adding input to the corpus */
Robert Swieckid50ed422017-11-13 23:32:26 +0100209 if (run->linux.hwCnts.newBBCnt > 0 || softCntPc > 0 || softCntEdge > 0 || softCntCmp > 0 ||
210 diff0 < 0 || diff1 < 0) {
Robert Swiecki92ec8d22016-11-21 01:10:18 +0100211 if (diff0 < 0) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100212 run->global->linux.hwCnts.cpuInstrCnt = run->linux.hwCnts.cpuInstrCnt;
Robert Swiecki92ec8d22016-11-21 01:10:18 +0100213 }
214 if (diff1 < 0) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100215 run->global->linux.hwCnts.cpuBranchCnt = run->linux.hwCnts.cpuBranchCnt;
Robert Swiecki92ec8d22016-11-21 01:10:18 +0100216 }
Robert Swiecki78633d12017-11-13 23:24:55 +0100217 run->global->linux.hwCnts.bbCnt += run->linux.hwCnts.newBBCnt;
218 run->global->linux.hwCnts.softCntPc += softCntPc;
219 run->global->linux.hwCnts.softCntEdge += softCntEdge;
220 run->global->linux.hwCnts.softCntCmp += softCntCmp;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200221
Robert Swieckie60f3532017-12-17 20:25:20 +0100222 LOG_I("Size:%zu (i,b,hw,edge,ip,cmp): %" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64
Robert Swiecki0b566112017-10-17 17:39:07 +0200223 "/%" PRIu64 "/%" PRIu64 ", Tot:%" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64
224 "/%" PRIu64 "/%" PRIu64,
Robert Swieckie7294ca2017-11-11 02:46:32 +0100225 run->dynamicFileSz, run->linux.hwCnts.cpuInstrCnt, run->linux.hwCnts.cpuBranchCnt,
Robert Swieckie60f3532017-12-17 20:25:20 +0100226 run->linux.hwCnts.newBBCnt, softCntEdge, softCntPc, softCntCmp,
Robert Swiecki78633d12017-11-13 23:24:55 +0100227 run->global->linux.hwCnts.cpuInstrCnt, run->global->linux.hwCnts.cpuBranchCnt,
Robert Swieckie60f3532017-12-17 20:25:20 +0100228 run->global->linux.hwCnts.bbCnt, run->global->linux.hwCnts.softCntEdge,
229 run->global->linux.hwCnts.softCntPc, run->global->linux.hwCnts.softCntCmp);
Jagger395df022016-08-21 01:13:25 +0200230
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100231 fuzz_addFileToFileQ(run->global, run->dynamicFile, run->dynamicFileSz);
dobinedf9f8d2018-01-21 13:57:02 +0100232
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100233 if (run->global->socketFuzzer.enabled) {
dobinedf9f8d2018-01-21 13:57:02 +0100234 LOG_D("SocketFuzzer: fuzz: new BB (perf)");
235 fuzz_notifySocketFuzzerNewCov(run->global);
236 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200237 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200238}
239
Robert Swieckid50ed422017-11-13 23:32:26 +0100240static void fuzz_sanCovFeedback(run_t* run) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100241 if (run->global->feedback.skipFeedbackOnTimeout && run->tmOutSignaled) {
Robert Swiecki53ec9e42017-02-15 20:34:27 +0100242 return;
243 }
244
Robert Swiecki0b566112017-10-17 17:39:07 +0200245 LOG_D("File size (Best/New): %zu, SanCov feedback (bb,dso): Best: [%" PRIu64 ",%" PRIu64
246 "] / New: [%" PRIu64 ",%" PRIu64 "], newBBs:%" PRIu64,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100247 run->dynamicFileSz, run->global->sanitizer.sanCovCnts.hitBBCnt,
248 run->global->sanitizer.sanCovCnts.iDsoCnt, run->sanCovCnts.hitBBCnt,
249 run->sanCovCnts.iDsoCnt, run->sanCovCnts.newBBCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200250
Robert Swieckia5b918a2018-03-07 23:59:53 +0100251 MX_SCOPED_LOCK(&run->global->feedback.feedback_mutex);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200252
Robert Swiecki78633d12017-11-13 23:24:55 +0100253 int64_t diff0 = run->global->linux.hwCnts.cpuInstrCnt - run->linux.hwCnts.cpuInstrCnt;
254 int64_t diff1 = run->global->linux.hwCnts.cpuBranchCnt - run->linux.hwCnts.cpuBranchCnt;
Jaggerd5738372016-08-17 20:12:15 +0200255
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200256 /*
257 * Keep mutated seed if:
Robert Swiecki142f9412016-03-14 19:22:01 +0100258 * a) Newly discovered (not met before) BBs
259 * b) More instrumented DSOs loaded
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100260 *
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200261 * TODO: (a) method can significantly assist to further improvements in interesting areas
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200262 * discovery if combined with seeds pool/queue support. If a runtime queue is maintained
263 * more interesting seeds can be saved between runs instead of instantly discarded
264 * based on current absolute elitism (only one mutated seed is promoted).
265 */
Jaggerd5738372016-08-17 20:12:15 +0200266
Robert Swieckia5b918a2018-03-07 23:59:53 +0100267 bool newCov = (run->sanCovCnts.newBBCnt > 0 ||
268 run->global->sanitizer.sanCovCnts.iDsoCnt < run->sanCovCnts.iDsoCnt);
Jaggerd5738372016-08-17 20:12:15 +0200269
Robert Swieckid158aac2016-11-01 23:14:12 +0100270 if (newCov || (diff0 < 0 || diff1 < 0)) {
Robert Swiecki0b566112017-10-17 17:39:07 +0200271 LOG_I("SanCov Update: fsize:%zu, newBBs:%" PRIu64 ", (Cur,New): %" PRIu64 "/%" PRIu64
272 ",%" PRIu64 "/%" PRIu64,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100273 run->dynamicFileSz, run->sanCovCnts.newBBCnt,
274 run->global->sanitizer.sanCovCnts.hitBBCnt, run->global->sanitizer.sanCovCnts.iDsoCnt,
275 run->sanCovCnts.hitBBCnt, run->sanCovCnts.iDsoCnt);
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200276
Robert Swieckia5b918a2018-03-07 23:59:53 +0100277 run->global->sanitizer.sanCovCnts.hitBBCnt += run->sanCovCnts.newBBCnt;
278 run->global->sanitizer.sanCovCnts.dsoCnt = run->sanCovCnts.dsoCnt;
279 run->global->sanitizer.sanCovCnts.iDsoCnt = run->sanCovCnts.iDsoCnt;
280 run->global->sanitizer.sanCovCnts.crashesCnt += run->sanCovCnts.crashesCnt;
281 run->global->sanitizer.sanCovCnts.newBBCnt = run->sanCovCnts.newBBCnt;
Anestis Bechtsoudisb78cf602016-01-07 13:10:50 +0200282
Robert Swieckia5b918a2018-03-07 23:59:53 +0100283 if (run->global->sanitizer.sanCovCnts.totalBBCnt < run->sanCovCnts.totalBBCnt) {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200284 /* Keep only the max value (for dlopen cases) to measure total target coverage */
Robert Swieckia5b918a2018-03-07 23:59:53 +0100285 run->global->sanitizer.sanCovCnts.totalBBCnt = run->sanCovCnts.totalBBCnt;
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200286 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200287
Robert Swiecki78633d12017-11-13 23:24:55 +0100288 run->global->linux.hwCnts.cpuInstrCnt = run->linux.hwCnts.cpuInstrCnt;
289 run->global->linux.hwCnts.cpuBranchCnt = run->linux.hwCnts.cpuBranchCnt;
Jaggerd5738372016-08-17 20:12:15 +0200290
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100291 fuzz_addFileToFileQ(run->global, run->dynamicFile, run->dynamicFileSz);
dobinedf9f8d2018-01-21 13:57:02 +0100292
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100293 if (run->global->socketFuzzer.enabled) {
dobinedf9f8d2018-01-21 13:57:02 +0100294 LOG_D("SocketFuzzer: fuzz: new BB (cov)");
295 fuzz_notifySocketFuzzerNewCov(run->global);
296 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200297 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200298}
299
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100300/* Return value indicates whether report file should be updated with the current verified crash */
Robert Swiecki9badb552018-01-12 01:42:08 +0100301static bool fuzz_runVerifier(run_t* run) {
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100302 if (!run->crashFileName[0] || !run->backtrace) {
303 return false;
304 }
305
Robert Swiecki9badb552018-01-12 01:42:08 +0100306 uint64_t backtrace = run->backtrace;
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100307
Robert Swiecki9badb552018-01-12 01:42:08 +0100308 char origCrashPath[PATH_MAX];
309 snprintf(origCrashPath, sizeof(origCrashPath), "%s", run->crashFileName);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100310 /* Workspace is inherited, just append a extra suffix */
311 char verFile[PATH_MAX];
312 snprintf(verFile, sizeof(verFile), "%s.verified", origCrashPath);
313
314 if (files_exists(verFile)) {
Robert Swiecki965af7f2018-01-12 02:30:14 +0100315 LOG_D("Crash file to verify '%s' is already verified as '%s'", origCrashPath, verFile);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100316 return false;
317 }
Robert Swiecki9badb552018-01-12 01:42:08 +0100318
319 for (int i = 0; i < _HF_VERIFIER_ITER; i++) {
Robert Swieckic4b573f2018-01-12 19:48:24 +0100320 LOG_I("Launching verifier for HASH: %" PRIx64 " (iteration: %d out of %d)", run->backtrace,
321 i + 1, _HF_VERIFIER_ITER);
Robert Swieckif2da05a2018-01-12 03:01:09 +0100322 run->timeStartedMillis = 0;
323 run->backtrace = 0;
324 run->access = 0;
Robert Swiecki9badb552018-01-12 01:42:08 +0100325 run->exception = 0;
Robert Swiecki9badb552018-01-12 01:42:08 +0100326 run->mainWorker = false;
Robert Swiecki9badb552018-01-12 01:42:08 +0100327
328 if (!subproc_Run(run)) {
329 LOG_F("subproc_Run()");
330 }
331
332 /* If stack hash doesn't match skip name tag and exit */
333 if (run->backtrace != backtrace) {
334 LOG_E("Verifier stack mismatch: (original) %" PRIx64 " != (new) %" PRIx64, backtrace,
335 run->backtrace);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100336 run->backtrace = backtrace;
337 return true;
Robert Swiecki9badb552018-01-12 01:42:08 +0100338 }
Robert Swiecki17b37eb2018-01-12 13:47:12 +0100339
Robert Swieckic4b573f2018-01-12 19:48:24 +0100340 LOG_I("Verifier for HASH: %" PRIx64 " (iteration: %d, left: %d). MATCH!", run->backtrace,
341 i + 1, _HF_VERIFIER_ITER - i - 1);
Robert Swiecki9badb552018-01-12 01:42:08 +0100342 }
343
Robert Swiecki9badb552018-01-12 01:42:08 +0100344 /* Copy file with new suffix & remove original copy */
345 int fd = TEMP_FAILURE_RETRY(open(verFile, O_CREAT | O_EXCL | O_WRONLY, 0600));
346 if (fd == -1 && errno == EEXIST) {
347 LOG_I("It seems that '%s' already exists, skipping", verFile);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100348 return false;
Robert Swiecki9badb552018-01-12 01:42:08 +0100349 }
350 if (fd == -1) {
351 PLOG_E("Couldn't create '%s'", verFile);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100352 return true;
Robert Swiecki9badb552018-01-12 01:42:08 +0100353 }
Robert Swiecki3ab16642018-01-12 18:08:37 +0100354 defer {
355 close(fd);
356 };
Robert Swiecki965af7f2018-01-12 02:30:14 +0100357 if (!files_writeToFd(fd, run->dynamicFile, run->dynamicFileSz)) {
358 LOG_E("Couldn't save verified file as '%s'", verFile);
359 unlink(verFile);
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100360 return true;
Robert Swiecki9badb552018-01-12 01:42:08 +0100361 }
362
363 LOG_I("Verified crash for HASH: %" PRIx64 " and saved it as '%s'", backtrace, verFile);
364 ATOMIC_POST_INC(run->global->cnts.verifiedCrashesCnt);
Robert Swiecki9badb552018-01-12 01:42:08 +0100365
366 return true;
367}
368
Robert Swiecki3ab16642018-01-12 18:08:37 +0100369static bool fuzz_fetchInput(run_t* run) {
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100370 if (fuzz_getState(run->global) == _HF_STATE_DYNAMIC_DRY_RUN) {
Robert Swiecki2bad0b42018-01-13 04:00:18 +0100371 run->mutationsPerRun = 0U;
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100372 if (input_prepareStaticFile(run, /* rewind= */ false)) {
Robert Swiecki3ab16642018-01-12 18:08:37 +0100373 return true;
374 }
Robert Swiecki308ebac2018-01-13 03:59:22 +0100375 fuzz_setDynamicMainState(run);
Robert Swiecki04dcac32018-03-02 03:05:26 +0100376 run->mutationsPerRun = run->global->mutate.mutationsPerRun;
Robert Swiecki3ab16642018-01-12 18:08:37 +0100377 }
378
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100379 if (fuzz_getState(run->global) == _HF_STATE_DYNAMIC_MAIN) {
Robert Swieckia9e34ed2018-01-17 00:31:56 +0100380 if (run->global->exe.externalCommand) {
381 if (!input_prepareExternalFile(run)) {
382 LOG_E("input_prepareFileExternally() failed");
383 return false;
384 }
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100385 } else if (!input_prepareDynamicInput(run)) {
386 LOG_E("input_prepareFileDynamically() failed");
Robert Swiecki3ab16642018-01-12 18:08:37 +0100387 return false;
388 }
389 }
390
Robert Swieckifb8a5b62018-01-14 05:16:59 +0100391 if (fuzz_getState(run->global) == _HF_STATE_STATIC) {
Robert Swieckia9e34ed2018-01-17 00:31:56 +0100392 if (run->global->exe.externalCommand) {
393 if (!input_prepareExternalFile(run)) {
394 LOG_E("input_prepareFileExternally() failed");
395 return false;
396 }
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100397 } else if (!input_prepareStaticFile(run, true /* rewind */)) {
398 LOG_E("input_prepareFile() failed");
Robert Swiecki3ab16642018-01-12 18:08:37 +0100399 return false;
400 }
401 }
402
Robert Swiecki0f2c30a2018-01-13 14:03:39 +0100403 if (run->global->exe.postExternalCommand && !input_postProcessFile(run)) {
404 LOG_E("input_postProcessFile() failed");
Robert Swiecki3ab16642018-01-12 18:08:37 +0100405 return false;
406 }
407
408 return true;
409}
410
Robert Swieckid50ed422017-11-13 23:32:26 +0100411static void fuzz_fuzzLoop(run_t* run) {
Robert Swieckie7294ca2017-11-11 02:46:32 +0100412 run->pid = 0;
Robert Swieckif2da05a2018-01-12 03:01:09 +0100413 run->timeStartedMillis = 0;
Robert Swieckie7294ca2017-11-11 02:46:32 +0100414 run->crashFileName[0] = '\0';
Robert Swieckif2da05a2018-01-12 03:01:09 +0100415 run->pc = 0;
416 run->backtrace = 0;
417 run->access = 0;
Robert Swieckie7294ca2017-11-11 02:46:32 +0100418 run->exception = 0;
419 run->report[0] = '\0';
420 run->mainWorker = true;
Robert Swiecki04dcac32018-03-02 03:05:26 +0100421 run->mutationsPerRun = run->global->mutate.mutationsPerRun;
Robert Swieckie7294ca2017-11-11 02:46:32 +0100422 run->dynamicFileSz = 0;
Robert Swiecki1f1a2f92018-01-15 15:26:37 +0100423 run->dynamicFileCopyFd = -1,
Robert Swieckia96d78d2016-03-14 16:50:50 +0100424
Robert Swieckif2da05a2018-01-12 03:01:09 +0100425 run->sanCovCnts.hitBBCnt = 0;
426 run->sanCovCnts.totalBBCnt = 0;
427 run->sanCovCnts.dsoCnt = 0;
428 run->sanCovCnts.newBBCnt = 0;
429 run->sanCovCnts.crashesCnt = 0;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100430
Robert Swieckif2da05a2018-01-12 03:01:09 +0100431 run->linux.hwCnts.cpuInstrCnt = 0;
432 run->linux.hwCnts.cpuBranchCnt = 0;
433 run->linux.hwCnts.bbCnt = 0;
434 run->linux.hwCnts.newBBCnt = 0;
Jagger190f0dc2015-09-05 16:41:22 +0200435
Robert Swiecki3ab16642018-01-12 18:08:37 +0100436 if (!fuzz_fetchInput(run)) {
437 LOG_F("Cound't prepare input for fuzzing");
Robert Swiecki92a31362017-02-24 16:21:40 +0100438 }
Robert Swiecki3ab16642018-01-12 18:08:37 +0100439 if (!subproc_Run(run)) {
440 LOG_F("Couldn't run fuzzed command");
Jagger190f0dc2015-09-05 16:41:22 +0200441 }
442
Robert Swieckia5b918a2018-03-07 23:59:53 +0100443 if (run->global->feedback.dynFileMethod != _HF_DYNFILE_NONE) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100444 fuzz_perfFeedback(run);
Robert Swiecki53ec9e42017-02-15 20:34:27 +0100445 }
Robert Swieckia5b918a2018-03-07 23:59:53 +0100446 if (run->global->feedback.dynFileMethod & _HF_DYNFILE_SANCOV) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100447 fuzz_sanCovFeedback(run);
Robert Swiecki0f937af2016-03-30 18:19:16 +0200448 }
Robert Swieckia5b918a2018-03-07 23:59:53 +0100449 if (run->global->cfg.useVerifier && !fuzz_runVerifier(run)) {
Robert Swiecki28cc4cb2018-01-12 02:18:29 +0100450 return;
Anestis Bechtsoudis5c86ebc2015-09-27 18:06:43 +0300451 }
Robert Swiecki78633d12017-11-13 23:24:55 +0100452 report_Report(run);
Jagger190f0dc2015-09-05 16:41:22 +0200453}
454
Robert Swiecki56276192018-01-21 15:43:02 +0100455static void fuzz_fuzzLoopSocket(run_t* run) {
dobinedf9f8d2018-01-21 13:57:02 +0100456 run->pid = 0;
457 run->timeStartedMillis = 0;
458 run->crashFileName[0] = '\0';
459 run->pc = 0;
460 run->backtrace = 0;
461 run->access = 0;
462 run->exception = 0;
463 run->report[0] = '\0';
464 run->mainWorker = true;
Robert Swiecki04dcac32018-03-02 03:05:26 +0100465 run->mutationsPerRun = run->global->mutate.mutationsPerRun;
dobinedf9f8d2018-01-21 13:57:02 +0100466 run->dynamicFileSz = 0;
467 run->dynamicFileCopyFd = -1,
468
469 run->sanCovCnts.hitBBCnt = 0;
470 run->sanCovCnts.totalBBCnt = 0;
471 run->sanCovCnts.dsoCnt = 0;
472 run->sanCovCnts.newBBCnt = 0;
473 run->sanCovCnts.crashesCnt = 0;
474
475 run->linux.hwCnts.cpuInstrCnt = 0;
476 run->linux.hwCnts.cpuBranchCnt = 0;
477 run->linux.hwCnts.bbCnt = 0;
478 run->linux.hwCnts.newBBCnt = 0;
479
480 LOG_I("------------------------------------------------------");
481
482 /* First iteration: Start target
483 Other iterations: re-start target, if necessary
484 subproc_Run() will decide by itself if a restart is necessary, via
485 subproc_New()
486 */
487 LOG_D("------[ 1: subproc_run");
488 if (!subproc_Run(run)) {
489 LOG_W("Couldn't run server");
490 }
491
492 /* Tell the external fuzzer to send data to target
493 The fuzzer will notify us when finished; block until then.
494 */
495 LOG_D("------[ 2: fetch input");
496 if (!fuzz_waitForExternalInput(run)) {
497 /* Fuzzer could not connect to target, and told us to
498 restart it. Do it on the next iteration. */
Robert Swiecki56276192018-01-21 15:43:02 +0100499 LOG_D("------[ 2.1: Target down, will restart it");
dobinedf9f8d2018-01-21 13:57:02 +0100500 run->hasCrashed = true;
501 return;
502 }
503
504 LOG_D("------[ 3: feedback");
Robert Swieckia5b918a2018-03-07 23:59:53 +0100505 if (run->global->feedback.dynFileMethod != _HF_DYNFILE_NONE) {
dobinedf9f8d2018-01-21 13:57:02 +0100506 fuzz_perfFeedback(run);
507 }
Robert Swieckia5b918a2018-03-07 23:59:53 +0100508 if (run->global->feedback.dynFileMethod & _HF_DYNFILE_SANCOV) {
dobinedf9f8d2018-01-21 13:57:02 +0100509 fuzz_sanCovFeedback(run);
510 }
Robert Swieckia5b918a2018-03-07 23:59:53 +0100511 if (run->global->cfg.useVerifier && !fuzz_runVerifier(run)) {
dobinedf9f8d2018-01-21 13:57:02 +0100512 return;
513 }
514
515 report_Report(run);
dobinedf9f8d2018-01-21 13:57:02 +0100516}
517
Robert Swieckid50ed422017-11-13 23:32:26 +0100518static void* fuzz_threadNew(void* arg) {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200519 honggfuzz_t* hfuzz = (honggfuzz_t*)arg;
Robert Swiecki66b65122017-11-11 02:55:55 +0100520 unsigned int fuzzNo = ATOMIC_POST_INC(hfuzz->threads.threadsActiveCnt);
Robert Swiecki0ec98112017-02-03 02:08:14 +0100521 LOG_I("Launched new fuzzing thread, no. #%" PRId32, fuzzNo);
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200522
Robert Swieckie7294ca2017-11-11 02:46:32 +0100523 run_t run = {
Robert Swiecki78633d12017-11-13 23:24:55 +0100524 .global = hfuzz,
Robert Swieckidecf14b2016-03-31 15:09:28 +0200525 .pid = 0,
526 .persistentPid = 0,
Robert Swieckibf8f8cc2017-11-09 00:42:50 +0100527 .dynfileqCurrent = NULL,
Robert Swiecki599dee12018-01-10 02:21:58 +0100528 .dynamicFile = NULL,
529 .dynamicFileFd = -1,
Jaggerfa3544a2016-08-30 02:55:55 +0200530 .fuzzNo = fuzzNo,
Jagger93253f72016-09-01 22:40:12 +0200531 .persistentSock = -1,
Robert Swiecki013bc9c2016-12-12 17:31:06 +0100532 .tmOutSignaled = false,
Robert Swiecki94d314c2018-02-07 21:23:00 +0100533 .origFileName = "[DYNAMIC]",
Robert Swiecki12800cd2016-03-31 15:38:10 +0200534
Robert Swieckib692f282016-08-25 16:21:08 +0200535 .linux.attachedPid = 0,
Robert Swieckidecf14b2016-03-31 15:09:28 +0200536 };
dobinedf9f8d2018-01-21 13:57:02 +0100537
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100538 /* Do not try to handle input files with socketfuzzer */
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100539 if (!hfuzz->socketFuzzer.enabled) {
Robert Swieckie9231d62018-03-02 03:35:11 +0100540 if (!(run.dynamicFile = files_mapSharedMem(hfuzz->mutate.maxFileSz, &run.dynamicFileFd,
541 "hfuzz-input", run.global->io.workDir))) {
542 LOG_F("Couldn't create an input file of size: %zu", hfuzz->mutate.maxFileSz);
dobinedf9f8d2018-01-21 13:57:02 +0100543 }
Robert Swiecki599dee12018-01-10 02:21:58 +0100544 }
Robert Swiecki41033812018-01-21 16:02:45 +0100545 defer {
546 if (run.dynamicFileFd != -1) {
547 close(run.dynamicFileFd);
548 }
549 };
Robert Swieckidecf14b2016-03-31 15:09:28 +0200550
Robert Swieckifc7520e2018-03-10 04:37:59 +0100551 if (!arch_archThreadInit(&run)) {
Robert Swiecki0f937af2016-03-30 18:19:16 +0200552 LOG_F("Could not initialize the thread");
553 }
554
Robert Swieckia96d78d2016-03-14 16:50:50 +0100555 for (;;) {
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200556 /* Check if dry run mode with verifier enabled */
Robert Swieckia5b918a2018-03-07 23:59:53 +0100557 if (run.global->mutate.mutationsPerRun == 0U && run.global->cfg.useVerifier &&
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100558 !hfuzz->socketFuzzer.enabled) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100559 if (ATOMIC_POST_INC(run.global->cnts.mutationsCnt) >= run.global->io.fileCnt) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100560 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200561 break;
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200562 }
563 }
564 /* Check for max iterations limit if set */
Robert Swiecki04dcac32018-03-02 03:05:26 +0100565 else if ((ATOMIC_POST_INC(run.global->cnts.mutationsCnt) >=
566 run.global->mutate.mutationsMax) &&
567 run.global->mutate.mutationsMax) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100568 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200569 break;
Robert Swiecki8d01b012017-02-19 15:48:11 +0100570 }
571
Robert Swieckie9231d62018-03-02 03:35:11 +0100572 input_setSize(&run, run.global->mutate.maxFileSz);
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100573 if (hfuzz->socketFuzzer.enabled) {
dobinedf9f8d2018-01-21 13:57:02 +0100574 fuzz_fuzzLoopSocket(&run);
575 } else {
576 fuzz_fuzzLoop(&run);
577 }
578
Robert Swiecki0dde76d2017-11-16 19:25:44 +0100579 if (fuzz_isTerminating()) {
Robert Swiecki069b48f2017-05-31 01:00:08 +0200580 break;
581 }
582
Robert Swieckia5b918a2018-03-07 23:59:53 +0100583 if (run.global->cfg.exitUponCrash && ATOMIC_GET(run.global->cnts.crashesCnt) > 0) {
Robert Swiecki069b48f2017-05-31 01:00:08 +0200584 LOG_I("Seen a crash. Terminating all fuzzing threads");
Robert Swiecki0dde76d2017-11-16 19:25:44 +0100585 fuzz_setTerminating();
Robert Swiecki069b48f2017-05-31 01:00:08 +0200586 break;
587 }
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000588 }
Robert Swiecki069b48f2017-05-31 01:00:08 +0200589
590 LOG_I("Terminating thread no. #%" PRId32, fuzzNo);
Robert Swiecki78633d12017-11-13 23:24:55 +0100591 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki82c707c2017-11-14 16:36:23 +0100592 pthread_kill(run.global->threads.mainThread, SIGALRM);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200593 return NULL;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000594}
595
Robert Swieckid50ed422017-11-13 23:32:26 +0100596static void fuzz_runThread(honggfuzz_t* hfuzz, pthread_t* thread, void* (*thread_func)(void*)) {
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000597 pthread_attr_t attr;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000598
robert.swiecki@gmail.com6f5c2392015-02-16 18:13:09 +0000599 pthread_attr_init(&attr);
Robert Swiecki33fb2842017-02-19 05:39:50 +0100600 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
robert.swiecki@gmail.com441089a2015-02-23 13:14:07 +0000601 pthread_attr_setstacksize(&attr, _HF_PTHREAD_STACKSIZE);
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200602 pthread_attr_setguardsize(&attr, (size_t)sysconf(_SC_PAGESIZE));
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000603
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200604 if (pthread_create(thread, &attr, thread_func, (void*)hfuzz) < 0) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200605 PLOG_F("Couldn't create a new thread");
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000606 }
607
Robert Swiecki33fb2842017-02-19 05:39:50 +0100608 pthread_attr_destroy(&attr);
609
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000610 return;
611}
612
Robert Swieckid50ed422017-11-13 23:32:26 +0100613void fuzz_threadsStart(honggfuzz_t* hfuzz, pthread_t* threads) {
robert.swiecki@gmail.com956276a2015-04-16 16:51:52 +0000614 if (!arch_archInit(hfuzz)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200615 LOG_F("Couldn't prepare arch for fuzzing");
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000616 }
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200617 if (!sanitizers_Init(hfuzz)) {
618 LOG_F("Couldn't prepare sanitizer options");
619 }
Jagger00265602016-03-10 02:36:27 +0100620 if (!sancov_Init(hfuzz)) {
621 LOG_F("Couldn't prepare sancov options");
622 }
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000623
plusundc64d052018-07-31 13:55:50 +0000624 mangle_init(hfuzz->cfg.only_printable);
625
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100626 if (hfuzz->socketFuzzer.enabled) {
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100627 /* Don't do dry run with socketFuzzer */
Robert Swiecki41033812018-01-21 16:02:45 +0100628 LOG_I("Entering phase - Feedback Driven Mode (SocketFuzzer)");
Robert Swiecki363510f2018-03-09 02:00:30 +0100629 hfuzz->feedback.state = _HF_STATE_DYNAMIC_MAIN;
Robert Swieckia5b918a2018-03-07 23:59:53 +0100630 } else if (hfuzz->feedback.dynFileMethod != _HF_DYNFILE_NONE) {
Robert Swiecki41033812018-01-21 16:02:45 +0100631 LOG_I("Entering phase 1/2: Dry Run");
Robert Swiecki363510f2018-03-09 02:00:30 +0100632 hfuzz->feedback.state = _HF_STATE_DYNAMIC_DRY_RUN;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100633 } else {
Robert Swiecki41033812018-01-21 16:02:45 +0100634 LOG_I("Entering phase: Static");
Robert Swiecki363510f2018-03-09 02:00:30 +0100635 hfuzz->feedback.state = _HF_STATE_STATIC;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100636 }
637
Robert Swiecki66b65122017-11-11 02:55:55 +0100638 for (size_t i = 0; i < hfuzz->threads.threadsMax; i++) {
Robert Swiecki33fb2842017-02-19 05:39:50 +0100639 fuzz_runThread(hfuzz, &threads[i], fuzz_threadNew);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000640 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000641}
Robert Swiecki33fb2842017-02-19 05:39:50 +0100642
Robert Swieckid50ed422017-11-13 23:32:26 +0100643void fuzz_threadsStop(honggfuzz_t* hfuzz, pthread_t* threads) {
Robert Swiecki66b65122017-11-11 02:55:55 +0100644 for (size_t i = 0; i < hfuzz->threads.threadsMax; i++) {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200645 void* retval;
Robert Swiecki33fb2842017-02-19 05:39:50 +0100646 if (pthread_join(threads[i], &retval) != 0) {
647 PLOG_F("Couldn't pthread_join() thread: %zu", i);
648 }
649 }
650 LOG_I("All threads done");
651}