blob: f073eb6c2d16422b6cd9a44fda623cc47d5b289e [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);
516
517 /* Try to identify if the target crashed.
518 This information will be used in the next iteration of
519 this loop, to restart the target if necessary.
520 The fuzzer will be also notified.
521
522 Crash identification does not need to work 100%, as the external fuzzer
523 can also detect timeouts on the target server, and will
524 notify us. */
525 LOG_D("------[ 4: reap child");
526 arch_reapChild(run);
527}
528
Robert Swieckid50ed422017-11-13 23:32:26 +0100529static void* fuzz_threadNew(void* arg) {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200530 honggfuzz_t* hfuzz = (honggfuzz_t*)arg;
Robert Swiecki66b65122017-11-11 02:55:55 +0100531 unsigned int fuzzNo = ATOMIC_POST_INC(hfuzz->threads.threadsActiveCnt);
Robert Swiecki0ec98112017-02-03 02:08:14 +0100532 LOG_I("Launched new fuzzing thread, no. #%" PRId32, fuzzNo);
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200533
Robert Swieckie7294ca2017-11-11 02:46:32 +0100534 run_t run = {
Robert Swiecki78633d12017-11-13 23:24:55 +0100535 .global = hfuzz,
Robert Swieckidecf14b2016-03-31 15:09:28 +0200536 .pid = 0,
537 .persistentPid = 0,
Robert Swieckibf8f8cc2017-11-09 00:42:50 +0100538 .dynfileqCurrent = NULL,
Robert Swiecki599dee12018-01-10 02:21:58 +0100539 .dynamicFile = NULL,
540 .dynamicFileFd = -1,
Jaggerfa3544a2016-08-30 02:55:55 +0200541 .fuzzNo = fuzzNo,
Jagger93253f72016-09-01 22:40:12 +0200542 .persistentSock = -1,
Robert Swiecki013bc9c2016-12-12 17:31:06 +0100543 .tmOutSignaled = false,
Robert Swiecki94d314c2018-02-07 21:23:00 +0100544 .origFileName = "[DYNAMIC]",
Robert Swiecki12800cd2016-03-31 15:38:10 +0200545
Robert Swieckib692f282016-08-25 16:21:08 +0200546 .linux.attachedPid = 0,
Robert Swieckidecf14b2016-03-31 15:09:28 +0200547 };
dobinedf9f8d2018-01-21 13:57:02 +0100548
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100549 /* Do not try to handle input files with socketfuzzer */
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100550 if (!hfuzz->socketFuzzer.enabled) {
Robert Swieckie9231d62018-03-02 03:35:11 +0100551 if (!(run.dynamicFile = files_mapSharedMem(hfuzz->mutate.maxFileSz, &run.dynamicFileFd,
552 "hfuzz-input", run.global->io.workDir))) {
553 LOG_F("Couldn't create an input file of size: %zu", hfuzz->mutate.maxFileSz);
dobinedf9f8d2018-01-21 13:57:02 +0100554 }
Robert Swiecki599dee12018-01-10 02:21:58 +0100555 }
Robert Swiecki41033812018-01-21 16:02:45 +0100556 defer {
557 if (run.dynamicFileFd != -1) {
558 close(run.dynamicFileFd);
559 }
560 };
Robert Swieckidecf14b2016-03-31 15:09:28 +0200561
Robert Swiecki78633d12017-11-13 23:24:55 +0100562 if (arch_archThreadInit(&run) == false) {
Robert Swiecki0f937af2016-03-30 18:19:16 +0200563 LOG_F("Could not initialize the thread");
564 }
565
Robert Swieckia96d78d2016-03-14 16:50:50 +0100566 for (;;) {
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200567 /* Check if dry run mode with verifier enabled */
Robert Swieckia5b918a2018-03-07 23:59:53 +0100568 if (run.global->mutate.mutationsPerRun == 0U && run.global->cfg.useVerifier &&
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100569 !hfuzz->socketFuzzer.enabled) {
Robert Swiecki82c707c2017-11-14 16:36:23 +0100570 if (ATOMIC_POST_INC(run.global->cnts.mutationsCnt) >= run.global->io.fileCnt) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100571 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200572 break;
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200573 }
574 }
575 /* Check for max iterations limit if set */
Robert Swiecki04dcac32018-03-02 03:05:26 +0100576 else if ((ATOMIC_POST_INC(run.global->cnts.mutationsCnt) >=
577 run.global->mutate.mutationsMax) &&
578 run.global->mutate.mutationsMax) {
Robert Swiecki78633d12017-11-13 23:24:55 +0100579 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200580 break;
Robert Swiecki8d01b012017-02-19 15:48:11 +0100581 }
582
Robert Swieckie9231d62018-03-02 03:35:11 +0100583 input_setSize(&run, run.global->mutate.maxFileSz);
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100584 if (hfuzz->socketFuzzer.enabled) {
dobinedf9f8d2018-01-21 13:57:02 +0100585 fuzz_fuzzLoopSocket(&run);
586 } else {
587 fuzz_fuzzLoop(&run);
588 }
589
Robert Swiecki0dde76d2017-11-16 19:25:44 +0100590 if (fuzz_isTerminating()) {
Robert Swiecki069b48f2017-05-31 01:00:08 +0200591 break;
592 }
593
Robert Swieckia5b918a2018-03-07 23:59:53 +0100594 if (run.global->cfg.exitUponCrash && ATOMIC_GET(run.global->cnts.crashesCnt) > 0) {
Robert Swiecki069b48f2017-05-31 01:00:08 +0200595 LOG_I("Seen a crash. Terminating all fuzzing threads");
Robert Swiecki0dde76d2017-11-16 19:25:44 +0100596 fuzz_setTerminating();
Robert Swiecki069b48f2017-05-31 01:00:08 +0200597 break;
598 }
robert.swiecki@gmail.comd4dd4df2015-02-18 00:50:12 +0000599 }
Robert Swiecki069b48f2017-05-31 01:00:08 +0200600
601 LOG_I("Terminating thread no. #%" PRId32, fuzzNo);
Robert Swiecki78633d12017-11-13 23:24:55 +0100602 ATOMIC_POST_INC(run.global->threads.threadsFinished);
Robert Swiecki82c707c2017-11-14 16:36:23 +0100603 pthread_kill(run.global->threads.mainThread, SIGALRM);
Robert Swiecki069b48f2017-05-31 01:00:08 +0200604 return NULL;
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000605}
606
Robert Swieckid50ed422017-11-13 23:32:26 +0100607static void fuzz_runThread(honggfuzz_t* hfuzz, pthread_t* thread, void* (*thread_func)(void*)) {
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000608 pthread_attr_t attr;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000609
robert.swiecki@gmail.com6f5c2392015-02-16 18:13:09 +0000610 pthread_attr_init(&attr);
Robert Swiecki33fb2842017-02-19 05:39:50 +0100611 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
robert.swiecki@gmail.com441089a2015-02-23 13:14:07 +0000612 pthread_attr_setstacksize(&attr, _HF_PTHREAD_STACKSIZE);
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200613 pthread_attr_setguardsize(&attr, (size_t)sysconf(_SC_PAGESIZE));
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000614
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200615 if (pthread_create(thread, &attr, thread_func, (void*)hfuzz) < 0) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200616 PLOG_F("Couldn't create a new thread");
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000617 }
618
Robert Swiecki33fb2842017-02-19 05:39:50 +0100619 pthread_attr_destroy(&attr);
620
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000621 return;
622}
623
Robert Swieckid50ed422017-11-13 23:32:26 +0100624void fuzz_threadsStart(honggfuzz_t* hfuzz, pthread_t* threads) {
robert.swiecki@gmail.com956276a2015-04-16 16:51:52 +0000625 if (!arch_archInit(hfuzz)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200626 LOG_F("Couldn't prepare arch for fuzzing");
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000627 }
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200628 if (!sanitizers_Init(hfuzz)) {
629 LOG_F("Couldn't prepare sanitizer options");
630 }
Jagger00265602016-03-10 02:36:27 +0100631 if (!sancov_Init(hfuzz)) {
632 LOG_F("Couldn't prepare sancov options");
633 }
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000634
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100635 if (hfuzz->socketFuzzer.enabled) {
Robert Swiecki5eeb29b2018-01-21 16:07:06 +0100636 /* Don't do dry run with socketFuzzer */
Robert Swiecki41033812018-01-21 16:02:45 +0100637 LOG_I("Entering phase - Feedback Driven Mode (SocketFuzzer)");
Robert Swiecki363510f2018-03-09 02:00:30 +0100638 hfuzz->feedback.state = _HF_STATE_DYNAMIC_MAIN;
Robert Swieckia5b918a2018-03-07 23:59:53 +0100639 } else if (hfuzz->feedback.dynFileMethod != _HF_DYNFILE_NONE) {
Robert Swiecki41033812018-01-21 16:02:45 +0100640 LOG_I("Entering phase 1/2: Dry Run");
Robert Swiecki363510f2018-03-09 02:00:30 +0100641 hfuzz->feedback.state = _HF_STATE_DYNAMIC_DRY_RUN;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100642 } else {
Robert Swiecki41033812018-01-21 16:02:45 +0100643 LOG_I("Entering phase: Static");
Robert Swiecki363510f2018-03-09 02:00:30 +0100644 hfuzz->feedback.state = _HF_STATE_STATIC;
Robert Swieckia96d78d2016-03-14 16:50:50 +0100645 }
646
Robert Swiecki66b65122017-11-11 02:55:55 +0100647 for (size_t i = 0; i < hfuzz->threads.threadsMax; i++) {
Robert Swiecki33fb2842017-02-19 05:39:50 +0100648 fuzz_runThread(hfuzz, &threads[i], fuzz_threadNew);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000649 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000650}
Robert Swiecki33fb2842017-02-19 05:39:50 +0100651
Robert Swieckid50ed422017-11-13 23:32:26 +0100652void fuzz_threadsStop(honggfuzz_t* hfuzz, pthread_t* threads) {
Robert Swiecki66b65122017-11-11 02:55:55 +0100653 for (size_t i = 0; i < hfuzz->threads.threadsMax; i++) {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200654 void* retval;
Robert Swiecki33fb2842017-02-19 05:39:50 +0100655 if (pthread_join(threads[i], &retval) != 0) {
656 PLOG_F("Couldn't pthread_join() thread: %zu", i);
657 }
658 }
659 LOG_I("All threads done");
660}