blob: 351c487e2bb5f0519034fc3043a2af6d5c859c5d [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.com772b33d2015-02-14 20:35:00 +00006 * Author: Robert Swiecki <swiecki@google.com> Felix Gröbert
7 * <groebert@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00008 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00009 * Copyright 2010-2015 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 "common.h"
26#include "fuzz.h"
27
28#include <errno.h>
29#include <fcntl.h>
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000030#include <inttypes.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.swiecki3bb518c2010-10-14 00:48:24 +000038#include <sys/mman.h>
39#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>
43#include <sys/wait.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000044#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000045#include <unistd.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000046
robert.swiecki3bb518c2010-10-14 00:48:24 +000047#include "arch.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000048#include "files.h"
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000049#include "log.h"
50#include "report.h"
51#include "util.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000052
53static void fuzz_mangleContent(honggfuzz_t * hfuzz, uint8_t * buf, off_t fileSz)
54{
robert.swieckicccbf0c2011-01-28 11:58:04 +000055 /*
56 * Just copy the file if "-r 0"
57 */
robert.swiecki@gmail.comb0383372015-02-13 14:17:27 +000058 uint64_t changesCnt = fileSz * hfuzz->flipRate;
59
60 if (changesCnt == 0ULL) {
robert.swieckiba512632011-01-28 11:57:26 +000061 return;
62 }
63
robert.swiecki3bb518c2010-10-14 00:48:24 +000064 if (hfuzz->flipMode == 'b') {
65 changesCnt *= 8UL;
66 }
67
68 changesCnt = util_rndGet(1, changesCnt);
69
70 for (uint64_t x = 0; x < changesCnt; x++) {
71 off_t pos = util_rndGet(0, fileSz - 1);
72
73 if (hfuzz->flipMode == 'b') {
74 buf[pos] ^= (1 << util_rndGet(0, 7));
75 } else {
76 buf[pos] = (uint8_t) util_rndGet(0, 255);
77 }
78 }
79}
80
81static void fuzz_getFileName(honggfuzz_t * hfuzz, char *fileName)
82{
robert.swieckiba512632011-01-28 11:57:26 +000083 struct timeval tv;
84 gettimeofday(&tv, NULL);
85
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000086 snprintf(fileName, PATH_MAX, ".honggfuzz.%d.%lu.%lu.%lu.%lu.%s",
87 (int)getpid(), (unsigned long int)tv.tv_sec,
88 (unsigned long int)tv.tv_usec,
89 (unsigned long int)util_rndGet(0, 1 << 30),
90 (unsigned long int)util_rndGet(0, 1 << 30), hfuzz->fileExtn);
robert.swiecki3bb518c2010-10-14 00:48:24 +000091
92 return;
93}
94
robert.swiecki@gmail.comd7aed312015-02-03 21:26:37 +000095static void fuzz_appendOrTrunc(int fd, off_t fileSz)
96{
97 const int chance_one_in_x = 10;
98 if (util_rndGet(1, chance_one_in_x) != 1) {
99 return;
100 }
101
robert.swiecki@gmail.com37f194e2015-02-03 21:35:07 +0000102 off_t maxSz = 2 * fileSz;
103 if (fileSz > (1024 * 1024 * 20)) {
104 maxSz = fileSz + (fileSz / 4);
105 }
106 if (fileSz > (1024 * 1024 * 100)) {
107 maxSz = fileSz;
108 }
109
110 off_t newSz = util_rndGet(1, maxSz);
robert.swiecki@gmail.comd7aed312015-02-03 21:26:37 +0000111 if (ftruncate(fd, newSz) == -1) {
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000112 LOGMSG_P(l_WARN,
113 "Couldn't truncate file from '%ld' to '%ld' bytes", (long)fileSz, (long)newSz);
robert.swiecki@gmail.comd7aed312015-02-03 21:26:37 +0000114 return;
115 }
116}
117
groebert@google.com1c7e3b02013-06-19 09:27:38 +0000118static bool fuzz_prepareFile(honggfuzz_t * hfuzz, char *fileName, int rnd_index)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000119{
robert.swiecki3bb518c2010-10-14 00:48:24 +0000120 off_t fileSz;
121 int srcfd;
122
123 uint8_t *buf = files_mapFileToRead(hfuzz->files[rnd_index], &fileSz, &srcfd);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000124 if (buf == NULL) {
robert.swiecki56b88012010-12-31 14:04:13 +0000125 LOGMSG(l_ERROR, "Couldn't open and map '%s' in R/O mode", hfuzz->files[rnd_index]);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000126 return false;
127 }
128
129 LOGMSG(l_DEBUG, "Mmaped '%s' in R/O mode, size: %d", hfuzz->files[rnd_index], fileSz);
130
131 int dstfd = open(fileName, O_CREAT | O_EXCL | O_RDWR, 0644);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000132 if (dstfd == -1) {
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000133 LOGMSG_P(l_ERROR,
134 "Couldn't create a temporary file '%s' in the current directory", fileName);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000135 munmap(buf, fileSz);
136 close(srcfd);
137 return false;
138 }
139
140 fuzz_mangleContent(hfuzz, buf, fileSz);
141
142 if (!files_writeToFd(dstfd, buf, fileSz)) {
143 munmap(buf, fileSz);
144 close(srcfd);
145 close(dstfd);
146 return false;
147 }
148
149 munmap(buf, fileSz);
robert.swiecki@gmail.comd7aed312015-02-03 21:26:37 +0000150
151 fuzz_appendOrTrunc(dstfd, fileSz);
152
robert.swiecki3bb518c2010-10-14 00:48:24 +0000153 close(srcfd);
154 close(dstfd);
155 return true;
156}
157
groebert@google.com1c7e3b02013-06-19 09:27:38 +0000158static bool fuzz_prepareFileExternally(honggfuzz_t * hfuzz, char *fileName, int rnd_index)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000159{
robert.swiecki3d505e22010-10-14 01:17:17 +0000160 off_t fileSz;
161 int srcfd;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000162
robert.swiecki3d505e22010-10-14 01:17:17 +0000163 int dstfd = open(fileName, O_CREAT | O_EXCL | O_RDWR, 0644);
164 if (dstfd == -1) {
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000165 LOGMSG_P(l_ERROR,
166 "Couldn't create a temporary file '%s' in the current directory", fileName);
robert.swiecki@gmail.comebc1cac2011-07-02 03:15:51 +0000167 return false;
168 }
169
170 LOGMSG(l_DEBUG, "Created '%f' as an input file", fileName);
171
172 if (hfuzz->inputFile) {
173 uint8_t *buf = files_mapFileToRead(hfuzz->files[rnd_index], &fileSz, &srcfd);
174 if (buf == NULL) {
175 LOGMSG(l_ERROR, "Couldn't open and map '%s' in R/O mode", hfuzz->files[rnd_index]);
176 close(dstfd);
177 return false;
178 }
179
180 LOGMSG(l_DEBUG, "Mmaped '%s' in R/O mode, size: %d", hfuzz->files[rnd_index], fileSz);
181
182 bool ret = files_writeToFd(dstfd, buf, fileSz);
robert.swiecki3d505e22010-10-14 01:17:17 +0000183 munmap(buf, fileSz);
184 close(srcfd);
robert.swiecki@gmail.comebc1cac2011-07-02 03:15:51 +0000185
186 if (!ret) {
187 close(dstfd);
188 return false;
189 }
robert.swiecki3d505e22010-10-14 01:17:17 +0000190 }
191
robert.swiecki3d505e22010-10-14 01:17:17 +0000192 close(dstfd);
193
robert.swiecki@gmail.com8a9df0e2015-02-13 17:08:06 +0000194 pid_t pid = vfork();
robert.swiecki3bb518c2010-10-14 00:48:24 +0000195 if (pid == -1) {
robert.swiecki@gmail.com8a9df0e2015-02-13 17:08:06 +0000196 LOGMSG_P(l_ERROR, "Couldn't vfork");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000197 return false;
198 }
199
200 if (!pid) {
robert.swiecki@gmail.comb5eab592015-02-13 17:26:25 +0000201#if defined(PR_SET_PDEATHSIG)
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000202 /*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000203 * Kill it if the main process goes down
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000204 */
robert.swiecki@gmail.comb5eab592015-02-13 17:26:25 +0000205 if (prctl(PR_SET_PDEATHSIG, (long)SIGKILL, 0L, 0L, 0L) == -1) {
206 LOGMSG_P(l_ERROR, "prctl(PR_SET_PDEATHSIG, SIGKILL) failed");
207 return false;
208 }
209#endif /* defined(PR_SET_PDEATHSIG) */
robert.swiecki3bb518c2010-10-14 00:48:24 +0000210 /*
robert.swiecki@gmail.comcdf18f92015-02-11 22:22:18 +0000211 * child performs the external file modifications
robert.swiecki3bb518c2010-10-14 00:48:24 +0000212 */
robert.swiecki3d505e22010-10-14 01:17:17 +0000213 execl(hfuzz->externalCommand, hfuzz->externalCommand, fileName, NULL);
groebert@google.comb857deb2010-10-21 19:09:29 +0000214 LOGMSG_P(l_FATAL, "Couldn't execute '%s %s'", hfuzz->externalCommand, fileName);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000215 return false;
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000216 }
robert.swiecki@gmail.com8a9df0e2015-02-13 17:08:06 +0000217
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000218 /*
219 * parent waits until child is done fuzzing the input file
220 */
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000221 int childStatus;
222 int flags = 0;
robert.swiecki@gmail.coma2291182015-02-13 16:56:27 +0000223#if defined(__WNOTHREAD)
224 flags |= __WNOTHREAD;
robert.swiecki@gmail.com8a9df0e2015-02-13 17:08:06 +0000225#endif /* defined(__WNOTHREAD) */
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000226 while (wait4(pid, &childStatus, flags, NULL) != pid) ;
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000227 if (WIFEXITED(childStatus)) {
228 LOGMSG(l_DEBUG, "External command exited with status %d", WEXITSTATUS(childStatus));
229 return true;
230 }
231 if (WIFSIGNALED(childStatus)) {
robert.swiecki@gmail.coma2291182015-02-13 16:56:27 +0000232 LOGMSG(l_ERROR, "External command terminated with signal %d", WTERMSIG(childStatus));
robert.swiecki3d505e22010-10-14 01:17:17 +0000233 return false;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000234 }
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000235 LOGMSG(l_FATAL, "External command terminated abnormally, status: %d", childStatus);
236 return false;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000237
238 abort(); /* NOTREACHED */
239}
240
robert.swiecki@gmail.com6ff9af82015-02-11 18:52:05 +0000241static int fuzz_numOfProc(honggfuzz_t * hfuzz)
242{
243 int i;
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000244 sem_getvalue(hfuzz->sem, &i);
robert.swiecki@gmail.com6ff9af82015-02-11 18:52:05 +0000245 return hfuzz->threadsMax - i;
246}
247
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000248static void *fuzz_threadNew(void *arg)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000249{
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000250 honggfuzz_t *hfuzz = (honggfuzz_t *) arg;
251 fuzzer_t fuzzer = {
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000252 .pid = 0,
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000253 .timeStarted = time(NULL),
254 .pc = 0ULL,
255 .backtrace = 0ULL,
256 .access = 0ULL,
257 .exception = 0,
258 };
robert.swiecki3bb518c2010-10-14 00:48:24 +0000259
groebert@google.com1c7e3b02013-06-19 09:27:38 +0000260 int rnd_index = util_rndGet(0, hfuzz->fileCnt - 1);
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000261 strncpy(fuzzer.origFileName, files_basename(hfuzz->files[rnd_index]), PATH_MAX);
262 fuzz_getFileName(hfuzz, fuzzer.fileName);
groebert@google.com1c7e3b02013-06-19 09:27:38 +0000263
robert.swiecki@gmail.com6ff9af82015-02-11 18:52:05 +0000264 if (hfuzz->externalCommand != NULL) {
265 if (!fuzz_prepareFileExternally(hfuzz, fuzzer.fileName, rnd_index)) {
266 exit(EXIT_FAILURE);
267 }
268 } else {
269 if (!fuzz_prepareFile(hfuzz, fuzzer.fileName, rnd_index)) {
270 exit(EXIT_FAILURE);
271 }
robert.swiecki@gmail.com1f98a162015-02-11 15:09:22 +0000272 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000273
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000274 fuzzer.pid = fork();
275 if (fuzzer.pid == -1) {
robert.swiecki3bb518c2010-10-14 00:48:24 +0000276 LOGMSG_P(l_FATAL, "Couldn't fork");
277 exit(EXIT_FAILURE);
278 }
279
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000280 if (!fuzzer.pid) {
robert.swiecki3bb518c2010-10-14 00:48:24 +0000281 /*
robert.swiecki@gmail.com6ff9af82015-02-11 18:52:05 +0000282 * Ok, kill the parent if this fails
robert.swiecki3bb518c2010-10-14 00:48:24 +0000283 */
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000284 if (!arch_launchChild(hfuzz, fuzzer.fileName)) {
groebert@google.com1bd4c212013-06-19 11:13:56 +0000285 LOGMSG(l_DEBUG, "Error launching child process, killing parent");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000286 kill(getppid(), SIGTERM);
287 exit(EXIT_FAILURE);
288 }
289 }
290
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000291 LOGMSG(l_INFO, "Launched new process, pid: %d, (%d/%d)", fuzzer.pid,
292 fuzz_numOfProc(hfuzz), hfuzz->threadsMax);
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000293
294 arch_reapChild(hfuzz, &fuzzer);
295 unlink(fuzzer.fileName);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000296 report_Report(hfuzz, fuzzer.report);
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000297
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000298 sem_post(hfuzz->sem);
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000299
300 return NULL;
301}
302
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000303static void *fuzz_threadPid(void *arg)
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000304{
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000305 honggfuzz_t *hfuzz = (honggfuzz_t *) arg;
306 if (!arch_prepareParent(hfuzz)) {
307 LOGMSG(l_FATAL, "Couldn't prepare parent for fuzzing");
robert.swiecki@gmail.com882900b2015-02-11 13:56:22 +0000308 }
309
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000310 fuzzer_t fuzzer = {
311 .pid = hfuzz->pid,
312 .timeStarted = time(NULL),
313 .pc = 0ULL,
314 .backtrace = 0ULL,
315 .access = 0ULL,
316 .exception = 0,
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000317 .report = {'\0'}
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000318 };
319
320 char fileName[] = ".honggfuzz.empty.XXXXXX";
321 int fd;
322 if ((fd = mkstemp(fileName)) == -1) {
323 LOGMSG_P(l_ERROR, "Couldn't create a temporary file");
324 return NULL;
325 }
326 close(fd);
327
328 strncpy(fuzzer.origFileName, "PID_FUZZING", PATH_MAX);
329 strncpy(fuzzer.fileName, fileName, PATH_MAX);
330
331 arch_reapChild(hfuzz, &fuzzer);
332 unlink(fuzzer.fileName);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000333 report_Report(hfuzz, fuzzer.report);
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000334
335 // There's no more hfuzz->pid to analyze. Just exit
336 LOGMSG(l_INFO, "PID: %d exited. Exiting", fuzzer.pid);
337 exit(EXIT_SUCCESS);
338
339 return NULL;
robert.swiecki3bb518c2010-10-14 00:48:24 +0000340}
341
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000342static void fuzz_runThread(honggfuzz_t * hfuzz, void *(*thread) (void *))
343{
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000344 pthread_attr_t attr;
345 pthread_attr_init(&attr);
346
347 pthread_t t;
348 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
349
350 if (pthread_create(&t, &attr, thread, (void *)hfuzz) < 0) {
351 LOGMSG_P(l_FATAL, "Couldn't create a new thread");
352 }
353
354 return;
355}
356
robert.swiecki3bb518c2010-10-14 00:48:24 +0000357void fuzz_main(honggfuzz_t * hfuzz)
358{
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000359 char semName[PATH_MAX];
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +0000360 snprintf(semName, sizeof(semName), "honggfuzz.%d.%d.%" PRIx64, getpid(),
361 (int)time(NULL), util_rndGet(1, 1ULL << 62));
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000362
robert.swiecki@gmail.com757ee192015-02-13 16:54:02 +0000363 hfuzz->sem = sem_open(semName, O_CREAT, 0644, hfuzz->threadsMax);
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000364 if (hfuzz->sem == SEM_FAILED) {
365 LOGMSG_P(l_FATAL, "sem_open() failed");
robert.swiecki@gmail.come7635392015-02-11 16:17:49 +0000366 }
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000367 // If we're doing a PID fuzzing, the parent of the PID will be a
368 // dedicated thread anyway
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000369 if (hfuzz->pid) {
370 fuzz_runThread(hfuzz, fuzz_threadPid);
371 } else {
372 if (!arch_prepareParent(hfuzz)) {
373 LOGMSG(l_FATAL, "Couldn't prepare parent for fuzzing");
374 }
robert.swiecki@gmail.comef829fa2011-06-22 13:51:57 +0000375 }
376
robert.swiecki3bb518c2010-10-14 00:48:24 +0000377 for (;;) {
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000378 if (sem_wait(hfuzz->sem) == -1) {
robert.swiecki@gmail.come507cb62015-02-11 17:14:49 +0000379 LOGMSG_P(l_FATAL, "sem_wait() failed");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000380 }
robert.swiecki@gmail.come507cb62015-02-11 17:14:49 +0000381
382 if (hfuzz->mutationsMax && (hfuzz->mutationsCnt >= hfuzz->mutationsMax)) {
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000383 /*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000384 * Sleep a bit to let any running fuzzers terminate
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000385 */
groebert@google.com20e368f2015-02-13 14:19:25 +0000386 usleep(1.2 * hfuzz->tmOut * 1000000);
robert.swiecki@gmail.come507cb62015-02-11 17:14:49 +0000387 LOGMSG(l_INFO, "Finished fuzzing %ld times.", hfuzz->mutationsMax);
robert.swiecki@gmail.com9bc725e2015-02-13 12:40:06 +0000388 sem_destroy(hfuzz->sem);
robert.swiecki@gmail.come507cb62015-02-11 17:14:49 +0000389 exit(EXIT_SUCCESS);
390 }
391
392 hfuzz->mutationsCnt++;
robert.swiecki@gmail.comc8443142015-02-13 13:46:40 +0000393 fuzz_runThread(hfuzz, fuzz_threadNew);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000394 }
395}