robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 1 | /* |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 2 | * |
robert.swiecki@gmail.com | 90e9911 | 2015-02-15 02:05:14 +0000 | [diff] [blame] | 3 | * honggfuzz - the main file |
| 4 | * ----------------------------------------- |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 5 | * |
robert.swiecki@gmail.com | 8531f69 | 2015-02-17 12:25:36 +0000 | [diff] [blame] | 6 | * Author: |
| 7 | * Robert Swiecki <swiecki@google.com> |
| 8 | * Felix Gröbert <groebert@google.com> |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 9 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 10 | * Copyright 2010-2015 by Google Inc. All Rights Reserved. |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 11 | * |
| 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.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 14 | * a copy of the License at |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 15 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 16 | * http://www.apache.org/licenses/LICENSE-2.0 |
robert.swiecki@gmail.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 17 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 18 | * 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.com | 3b630b4 | 2015-02-16 10:53:53 +0000 | [diff] [blame] | 23 | * |
robert.swiecki@gmail.com | 772b33d | 2015-02-14 20:35:00 +0000 | [diff] [blame] | 24 | */ |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 25 | |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 26 | #include <inttypes.h> |
robert.swiecki@gmail.com | ba85c3e | 2015-02-02 14:55:16 +0000 | [diff] [blame] | 27 | #include <getopt.h> |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 28 | #include <signal.h> |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 29 | #include <stdio.h> |
| 30 | #include <stdlib.h> |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 31 | #include <string.h> |
robert.swiecki@gmail.com | ba85c3e | 2015-02-02 14:55:16 +0000 | [diff] [blame] | 32 | #include <time.h> |
| 33 | #include <unistd.h> |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 34 | |
| 35 | #include "common.h" |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 36 | #include "cmdline.h" |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 37 | #include "display.h" |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 38 | #include "log.h" |
| 39 | #include "files.h" |
| 40 | #include "fuzz.h" |
| 41 | #include "util.h" |
| 42 | |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 43 | static int sigReceived = 0; |
| 44 | |
Robert Swiecki | c6a48b1 | 2016-03-11 17:41:57 +0100 | [diff] [blame^] | 45 | /* |
| 46 | * CygWin/MinGW incorrectly copies stack during fork(), so we need to keep some |
| 47 | * structures in the data section |
| 48 | */ |
| 49 | honggfuzz_t hfuzz; |
| 50 | char *myargs[1024]; |
| 51 | |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 52 | void 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 | |
| 62 | static 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 | |
| 73 | static 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 | } |
Jagger | 848c4fc | 2016-03-11 01:34:53 +0100 | [diff] [blame] | 85 | } |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 86 | |
Jagger | 848c4fc | 2016-03-11 01:34:53 +0100 | [diff] [blame] | 87 | static void setupSignalsPostThr(void) |
| 88 | { |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 89 | 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 | } |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 106 | /* 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.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 118 | int main(int argc, char **argv) |
| 119 | { |
Robert Swiecki | c6a48b1 | 2016-03-11 17:41:57 +0100 | [diff] [blame^] | 120 | /* |
| 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 Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 130 | LOG_F("Parsing of the cmd-line arguments failed"); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 131 | } |
| 132 | |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 133 | if (!files_init(&hfuzz)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 134 | LOG_F("Couldn't load input files"); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 135 | exit(EXIT_FAILURE); |
| 136 | } |
| 137 | |
robert.swiecki@gmail.com | 4f1124f | 2015-04-21 17:12:22 +0000 | [diff] [blame] | 138 | if (hfuzz.dictionaryFile && (files_parseDictionary(&hfuzz) == false)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 139 | LOG_F("Couldn't parse dictionary file ('%s')", hfuzz.dictionaryFile); |
robert.swiecki@gmail.com | 4f1124f | 2015-04-21 17:12:22 +0000 | [diff] [blame] | 140 | } |
| 141 | |
Anestis Bechtsoudis | d59af69 | 2015-09-21 15:15:05 +0300 | [diff] [blame] | 142 | if (hfuzz.blacklistFile && (files_parseBlacklist(&hfuzz) == false)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 143 | LOG_F("Couldn't parse stackhash blacklist file ('%s')", hfuzz.blacklistFile); |
Anestis Bechtsoudis | d59af69 | 2015-09-21 15:15:05 +0300 | [diff] [blame] | 144 | } |
| 145 | |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 146 | setupSignalsPreThr(); |
| 147 | setupTimer(); |
| 148 | |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 149 | /* |
| 150 | * So far so good |
| 151 | */ |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 152 | fuzz_threads(&hfuzz); |
| 153 | setupSignalsPostThr(); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 154 | |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 155 | 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.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 198 | } |