blob: 30bedbe60fd77d47637b272e799e327ec2a95323 [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 - the main file
4 * -----------------------------------------
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00005 *
robert.swiecki@gmail.com8531f692015-02-17 12:25:36 +00006 * Author:
7 * Robert Swiecki <swiecki@google.com>
8 * Felix Gröbert <groebert@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00009 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000010 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000011 *
12 * Licensed under the Apache License, Version 2.0 (the "License"); you may
13 * not use this file except in compliance with the License. You may obtain
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000014 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000015 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000016 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000017 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000018 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
21 * implied. See the License for the specific language governing
22 * permissions and limitations under the License.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000023 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000024 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000025
Robert Swieckic8c32db2015-10-09 18:06:22 +020026#include <inttypes.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000027#include <getopt.h>
Jagger08816fd2016-03-11 01:32:38 +010028#include <signal.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000029#include <stdio.h>
30#include <stdlib.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000031#include <string.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000032#include <time.h>
33#include <unistd.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000034
35#include "common.h"
Robert Swieckic8c32db2015-10-09 18:06:22 +020036#include "cmdline.h"
Jagger08816fd2016-03-11 01:32:38 +010037#include "display.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000038#include "log.h"
39#include "files.h"
40#include "fuzz.h"
41#include "util.h"
42
Jagger08816fd2016-03-11 01:32:38 +010043static int sigReceived = 0;
44
Robert Swieckic6a48b12016-03-11 17:41:57 +010045/*
46 * CygWin/MinGW incorrectly copies stack during fork(), so we need to keep some
47 * structures in the data section
48 */
49honggfuzz_t hfuzz;
50char *myargs[1024];
51
Jagger08816fd2016-03-11 01:32:38 +010052void sigHandler(int sig)
53{
54 /* We should not terminate upon SIGALRM delivery */
55 if (sig == SIGALRM) {
56 return;
57 }
58
59 sigReceived = sig;
60}
61
62static void setupTimer(void)
63{
64 struct itimerval it = {
65 .it_value = {.tv_sec = 0,.tv_usec = 1},
66 .it_interval = {.tv_sec = 1,.tv_usec = 0},
67 };
68 if (setitimer(ITIMER_REAL, &it, NULL) == -1) {
69 PLOG_F("setitimer(ITIMER_REAL)");
70 }
71}
72
73static void setupSignalsPreThr(void)
74{
75 /* Block signals which should be handled by the main thread */
76 sigset_t ss;
77 sigemptyset(&ss);
78 sigaddset(&ss, SIGTERM);
79 sigaddset(&ss, SIGINT);
80 sigaddset(&ss, SIGQUIT);
81 sigaddset(&ss, SIGALRM);
82 if (sigprocmask(SIG_BLOCK, &ss, NULL) != 0) {
83 PLOG_F("pthread_sigmask(SIG_BLOCK)");
84 }
Jagger848c4fc2016-03-11 01:34:53 +010085}
Jagger08816fd2016-03-11 01:32:38 +010086
Jagger848c4fc2016-03-11 01:34:53 +010087static void setupSignalsPostThr(void)
88{
Jagger08816fd2016-03-11 01:32:38 +010089 struct sigaction sa = {
90 .sa_handler = sigHandler,
91 .sa_flags = 0,
92 };
93 sigemptyset(&sa.sa_mask);
94 if (sigaction(SIGTERM, &sa, NULL) == -1) {
95 PLOG_F("sigaction(SIGTERM) failed");
96 }
97 if (sigaction(SIGINT, &sa, NULL) == -1) {
98 PLOG_F("sigaction(SIGINT) failed");
99 }
100 if (sigaction(SIGQUIT, &sa, NULL) == -1) {
101 PLOG_F("sigaction(SIGQUIT) failed");
102 }
103 if (sigaction(SIGALRM, &sa, NULL) == -1) {
104 PLOG_F("sigaction(SIGALRM) failed");
105 }
Jagger08816fd2016-03-11 01:32:38 +0100106 /* Unblock signals which should be handled by the main thread */
107 sigset_t ss;
108 sigemptyset(&ss);
109 sigaddset(&ss, SIGTERM);
110 sigaddset(&ss, SIGINT);
111 sigaddset(&ss, SIGQUIT);
112 sigaddset(&ss, SIGALRM);
113 if (sigprocmask(SIG_UNBLOCK, &ss, NULL) != 0) {
114 PLOG_F("pthread_sigmask(SIG_BLOCK)");
115 }
116}
117
robert.swiecki3bb518c2010-10-14 00:48:24 +0000118int main(int argc, char **argv)
119{
Robert Swieckic6a48b12016-03-11 17:41:57 +0100120 /*
121 * Work around CygWin/MinGW
122 */
123 size_t i;
124 for (i = 0U; i < (ARRAYSIZE(myargs) - 1); i++) {
125 myargs[i] = argv[i];
126 }
127 myargs[i] = NULL;
128
129 if (cmdlineParse(argc, myargs, &hfuzz) == false) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200130 LOG_F("Parsing of the cmd-line arguments failed");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000131 }
132
robert.swiecki3bb518c2010-10-14 00:48:24 +0000133 if (!files_init(&hfuzz)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200134 LOG_F("Couldn't load input files");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000135 exit(EXIT_FAILURE);
136 }
137
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000138 if (hfuzz.dictionaryFile && (files_parseDictionary(&hfuzz) == false)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200139 LOG_F("Couldn't parse dictionary file ('%s')", hfuzz.dictionaryFile);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000140 }
141
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300142 if (hfuzz.blacklistFile && (files_parseBlacklist(&hfuzz) == false)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200143 LOG_F("Couldn't parse stackhash blacklist file ('%s')", hfuzz.blacklistFile);
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300144 }
145
Jagger08816fd2016-03-11 01:32:38 +0100146 setupSignalsPreThr();
147 setupTimer();
148
robert.swiecki3bb518c2010-10-14 00:48:24 +0000149 /*
150 * So far so good
151 */
Jagger08816fd2016-03-11 01:32:38 +0100152 fuzz_threads(&hfuzz);
153 setupSignalsPostThr();
robert.swiecki3bb518c2010-10-14 00:48:24 +0000154
Jagger08816fd2016-03-11 01:32:38 +0100155 for (;;) {
156 if (hfuzz.useScreen) {
157 display_display(&hfuzz);
158 }
159 if (sigReceived > 0) {
160 break;
161 }
162 if (__sync_fetch_and_add(&hfuzz.threadsFinished, 0UL) >= hfuzz.threadsMax) {
163 break;
164 }
165 pause();
166 }
167
168 if (sigReceived > 0) {
169 LOG_I("Signal %d (%s) received, terminating", sigReceived, strsignal(sigReceived));
170 }
171
172 /* Clean-up global buffers */
173 free(hfuzz.files);
174 free(hfuzz.dynamicFileBest);
175 if (hfuzz.dictionary) {
176 for (size_t i = 0; i < hfuzz.dictionaryCnt; i++) {
177 free(hfuzz.dictionary[i]);
178 }
179 free(hfuzz.dictionary);
180 }
181 if (hfuzz.blacklist) {
182 free(hfuzz.blacklist);
183 }
184 if (hfuzz.sanOpts.asanOpts) {
185 free(hfuzz.sanOpts.asanOpts);
186 }
187 if (hfuzz.sanOpts.ubsanOpts) {
188 free(hfuzz.sanOpts.ubsanOpts);
189 }
190 if (hfuzz.sanOpts.msanOpts) {
191 free(hfuzz.sanOpts.msanOpts);
192 }
193 if (hfuzz.pidCmd) {
194 free(hfuzz.pidCmd);
195 }
196
197 exit(EXIT_SUCCESS);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000198}