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; |
Robert Swiecki | c6a48b1 | 2016-03-11 17:41:57 +0100 | [diff] [blame] | 50 | |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 51 | void sigHandler(int sig) |
| 52 | { |
| 53 | /* We should not terminate upon SIGALRM delivery */ |
| 54 | if (sig == SIGALRM) { |
| 55 | return; |
| 56 | } |
| 57 | |
| 58 | sigReceived = sig; |
| 59 | } |
| 60 | |
| 61 | static void setupTimer(void) |
| 62 | { |
| 63 | struct itimerval it = { |
Robert Swiecki | 37778e0 | 2016-03-15 15:45:28 +0100 | [diff] [blame] | 64 | .it_value = {.tv_sec = 1,.tv_usec = 0}, |
Robert Swiecki | 05783bb | 2016-07-26 15:43:48 +0200 | [diff] [blame] | 65 | .it_interval = {.tv_sec = 1,.tv_usec = 0}, |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 66 | }; |
| 67 | if (setitimer(ITIMER_REAL, &it, NULL) == -1) { |
| 68 | PLOG_F("setitimer(ITIMER_REAL)"); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | static void setupSignalsPreThr(void) |
| 73 | { |
Jagger | fbd4ae1 | 2016-09-02 02:26:02 +0200 | [diff] [blame] | 74 | /* Block signals which should be handled or blocked in the main thread */ |
Jagger | 33cce5d | 2016-04-16 20:10:36 +0200 | [diff] [blame] | 75 | sigset_t ss; |
Jagger | 090de22 | 2016-04-16 20:05:13 +0200 | [diff] [blame] | 76 | sigemptyset(&ss); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 77 | sigaddset(&ss, SIGTERM); |
| 78 | sigaddset(&ss, SIGINT); |
| 79 | sigaddset(&ss, SIGQUIT); |
Jagger | 33cce5d | 2016-04-16 20:10:36 +0200 | [diff] [blame] | 80 | sigaddset(&ss, SIGALRM); |
Jagger | ac75f26 | 2016-08-20 12:38:20 +0200 | [diff] [blame] | 81 | sigaddset(&ss, SIGPIPE); |
Jagger | fbd4ae1 | 2016-09-02 02:26:02 +0200 | [diff] [blame] | 82 | sigaddset(&ss, SIGIO); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 83 | if (sigprocmask(SIG_BLOCK, &ss, NULL) != 0) { |
| 84 | PLOG_F("pthread_sigmask(SIG_BLOCK)"); |
| 85 | } |
Jagger | 848c4fc | 2016-03-11 01:34:53 +0100 | [diff] [blame] | 86 | } |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 87 | |
Jagger | 848c4fc | 2016-03-11 01:34:53 +0100 | [diff] [blame] | 88 | static void setupSignalsPostThr(void) |
| 89 | { |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 90 | struct sigaction sa = { |
| 91 | .sa_handler = sigHandler, |
| 92 | .sa_flags = 0, |
| 93 | }; |
| 94 | sigemptyset(&sa.sa_mask); |
| 95 | if (sigaction(SIGTERM, &sa, NULL) == -1) { |
| 96 | PLOG_F("sigaction(SIGTERM) failed"); |
| 97 | } |
| 98 | if (sigaction(SIGINT, &sa, NULL) == -1) { |
| 99 | PLOG_F("sigaction(SIGINT) failed"); |
| 100 | } |
| 101 | if (sigaction(SIGQUIT, &sa, NULL) == -1) { |
| 102 | PLOG_F("sigaction(SIGQUIT) failed"); |
| 103 | } |
Jagger | 33cce5d | 2016-04-16 20:10:36 +0200 | [diff] [blame] | 104 | if (sigaction(SIGALRM, &sa, NULL) == -1) { |
| 105 | PLOG_F("sigaction(SIGQUIT) failed"); |
| 106 | } |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 107 | /* Unblock signals which should be handled by the main thread */ |
| 108 | sigset_t ss; |
| 109 | sigemptyset(&ss); |
| 110 | sigaddset(&ss, SIGTERM); |
| 111 | sigaddset(&ss, SIGINT); |
| 112 | sigaddset(&ss, SIGQUIT); |
Jagger | 3846dfc | 2016-04-16 20:06:16 +0200 | [diff] [blame] | 113 | sigaddset(&ss, SIGALRM); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 114 | if (sigprocmask(SIG_UNBLOCK, &ss, NULL) != 0) { |
Jagger | 33cce5d | 2016-04-16 20:10:36 +0200 | [diff] [blame] | 115 | PLOG_F("pthread_sigmask(SIG_UNBLOCK)"); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 116 | } |
| 117 | } |
| 118 | |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 119 | int main(int argc, char **argv) |
| 120 | { |
Robert Swiecki | c6a48b1 | 2016-03-11 17:41:57 +0100 | [diff] [blame] | 121 | /* |
| 122 | * Work around CygWin/MinGW |
| 123 | */ |
Robert Swiecki | 37778e0 | 2016-03-15 15:45:28 +0100 | [diff] [blame] | 124 | char **myargs = (char **)util_Malloc(sizeof(char *) * (argc + 1)); |
Anestis Bechtsoudis | a419873 | 2016-04-27 12:27:39 +0300 | [diff] [blame] | 125 | defer { |
| 126 | free(myargs); |
| 127 | }; |
Jagger | 1ebc6dc | 2016-03-12 01:39:09 +0100 | [diff] [blame] | 128 | |
| 129 | int i; |
| 130 | for (i = 0U; i < argc; i++) { |
Robert Swiecki | c6a48b1 | 2016-03-11 17:41:57 +0100 | [diff] [blame] | 131 | myargs[i] = argv[i]; |
| 132 | } |
| 133 | myargs[i] = NULL; |
| 134 | |
| 135 | if (cmdlineParse(argc, myargs, &hfuzz) == false) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 136 | LOG_F("Parsing of the cmd-line arguments failed"); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 137 | } |
| 138 | |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 139 | if (!files_init(&hfuzz)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 140 | LOG_F("Couldn't load input files"); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 141 | exit(EXIT_FAILURE); |
| 142 | } |
| 143 | |
robert.swiecki@gmail.com | 4f1124f | 2015-04-21 17:12:22 +0000 | [diff] [blame] | 144 | if (hfuzz.dictionaryFile && (files_parseDictionary(&hfuzz) == false)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 145 | LOG_F("Couldn't parse dictionary file ('%s')", hfuzz.dictionaryFile); |
robert.swiecki@gmail.com | 4f1124f | 2015-04-21 17:12:22 +0000 | [diff] [blame] | 146 | } |
| 147 | |
Anestis Bechtsoudis | d59af69 | 2015-09-21 15:15:05 +0300 | [diff] [blame] | 148 | if (hfuzz.blacklistFile && (files_parseBlacklist(&hfuzz) == false)) { |
Robert Swiecki | c8c32db | 2015-10-09 18:06:22 +0200 | [diff] [blame] | 149 | LOG_F("Couldn't parse stackhash blacklist file ('%s')", hfuzz.blacklistFile); |
Anestis Bechtsoudis | d59af69 | 2015-09-21 15:15:05 +0300 | [diff] [blame] | 150 | } |
| 151 | |
Jagger | 4aac9fe | 2016-08-28 17:35:48 +0200 | [diff] [blame] | 152 | if (hfuzz.dynFileMethod != _HF_DYNFILE_NONE) { |
Jagger | 5b81a50 | 2016-09-07 20:48:32 +0200 | [diff] [blame] | 153 | hfuzz.feedback = files_mapSharedMem(sizeof(feedback_t), &hfuzz.bbFd, hfuzz.workDir); |
Jagger | 4aac9fe | 2016-08-28 17:35:48 +0200 | [diff] [blame] | 154 | if (hfuzz.feedback == MAP_FAILED) { |
Jagger | 5b81a50 | 2016-09-07 20:48:32 +0200 | [diff] [blame] | 155 | LOG_F("files_mapSharedMem(sz=%zu, dir='%s') failed", sizeof(feedback_t), hfuzz.workDir); |
Jagger | 4aac9fe | 2016-08-28 17:35:48 +0200 | [diff] [blame] | 156 | } |
| 157 | } |
| 158 | |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 159 | /* |
| 160 | * So far so good |
| 161 | */ |
Robert Swiecki | 37778e0 | 2016-03-15 15:45:28 +0100 | [diff] [blame] | 162 | setupSignalsPreThr(); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 163 | fuzz_threads(&hfuzz); |
| 164 | setupSignalsPostThr(); |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 165 | |
Robert Swiecki | 37778e0 | 2016-03-15 15:45:28 +0100 | [diff] [blame] | 166 | setupTimer(); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 167 | for (;;) { |
| 168 | if (hfuzz.useScreen) { |
| 169 | display_display(&hfuzz); |
| 170 | } |
| 171 | if (sigReceived > 0) { |
| 172 | break; |
| 173 | } |
Jagger | d34417d | 2016-03-16 01:26:54 +0100 | [diff] [blame] | 174 | if (ATOMIC_GET(hfuzz.threadsFinished) >= hfuzz.threadsMax) { |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 175 | break; |
| 176 | } |
| 177 | pause(); |
| 178 | } |
| 179 | |
| 180 | if (sigReceived > 0) { |
| 181 | LOG_I("Signal %d (%s) received, terminating", sigReceived, strsignal(sigReceived)); |
Jagger | 4f97d77 | 2016-07-20 20:55:51 +0200 | [diff] [blame] | 182 | return EXIT_SUCCESS; |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | /* Clean-up global buffers */ |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 186 | if (hfuzz.blacklist) { |
| 187 | free(hfuzz.blacklist); |
| 188 | } |
| 189 | if (hfuzz.sanOpts.asanOpts) { |
| 190 | free(hfuzz.sanOpts.asanOpts); |
| 191 | } |
| 192 | if (hfuzz.sanOpts.ubsanOpts) { |
| 193 | free(hfuzz.sanOpts.ubsanOpts); |
| 194 | } |
| 195 | if (hfuzz.sanOpts.msanOpts) { |
| 196 | free(hfuzz.sanOpts.msanOpts); |
| 197 | } |
Jagger | 247c3b4 | 2016-03-21 23:24:05 +0100 | [diff] [blame] | 198 | if (hfuzz.linux.pidCmd) { |
| 199 | free(hfuzz.linux.pidCmd); |
Jagger | 08816fd | 2016-03-11 01:32:38 +0100 | [diff] [blame] | 200 | } |
| 201 | |
Robert Swiecki | 37778e0 | 2016-03-15 15:45:28 +0100 | [diff] [blame] | 202 | return EXIT_SUCCESS; |
robert.swiecki | 3bb518c | 2010-10-14 00:48:24 +0000 | [diff] [blame] | 203 | } |