blob: df54e5357e76328db1862b0866258cf290b19ea6 [file] [log] [blame]
Robert Swieckia88f96f2015-10-09 16:47:39 +02001/*
2
3 honggfuzz - cmdline parsing
4
5 -----------------------------------------
6
7 Copyright 2014 Google Inc. All Rights Reserved.
8
9 Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14
15 Unless required by applicable law or agreed to in writing, software
16 distributed under the License is distributed on an "AS IS" BASIS,
17 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 See the License for the specific language governing permissions and
19 limitations under the License.
20
21*/
22
23#include "cmdline.h"
24
25#include <ctype.h>
26#include <errno.h>
27#include <getopt.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020028#include <inttypes.h>
29#include <limits.h>
Robert Swiecki846ccd72017-01-12 17:52:23 +010030#if defined(_HF_ARCH_LINUX)
31#include <sched.h>
Robert Swiecki4e595fb2017-10-11 17:26:51 +020032#endif /* defined(_HF_ARCH_LINUX) */
Robert Swiecki846ccd72017-01-12 17:52:23 +010033#include <signal.h>
Robert Swiecki15801e82018-11-20 15:59:25 +010034#include <stdint.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020035#include <stdio.h>
Robert Swieckid0fa62c2017-09-28 18:11:05 +020036#include <stdlib.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020037#include <string.h>
Robert Swieckif8292582018-01-10 16:19:18 +010038#include <sys/mman.h>
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010039#include <sys/queue.h>
Robert Swieckia35d9d82017-12-15 22:00:41 +010040#include <sys/stat.h>
41#include <sys/types.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020042#include <unistd.h>
43
Robert Swiecki8a1fc672018-01-25 23:22:47 +010044#include "display.h"
Robert Swiecki246af3e2018-01-05 14:56:32 +010045#include "libhfcommon/common.h"
46#include "libhfcommon/files.h"
47#include "libhfcommon/log.h"
48#include "libhfcommon/util.h"
Robert Swieckia88f96f2015-10-09 16:47:39 +020049
50struct custom_option {
51 struct option opt;
Robert Swiecki4e595fb2017-10-11 17:26:51 +020052 const char* descr;
Robert Swieckia88f96f2015-10-09 16:47:39 +020053};
54
Robert Swiecki97d0cee2017-12-18 00:17:50 +010055static bool checkFor_FILE_PLACEHOLDER(const char* const* args) {
Robert Swieckia88f96f2015-10-09 16:47:39 +020056 for (int x = 0; args[x]; x++) {
Robert Swieckid50ed422017-11-13 23:32:26 +010057 if (strstr(args[x], _HF_FILE_PLACEHOLDER)) return true;
Robert Swieckia88f96f2015-10-09 16:47:39 +020058 }
59 return false;
60}
61
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010062static bool cmdlineCheckBinaryType(honggfuzz_t* hfuzz) {
Robert Swieckif8292582018-01-10 16:19:18 +010063 int fd;
64 off_t fileSz;
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010065 uint8_t* map = files_mapFile(hfuzz->exe.cmdline[0], &fileSz, &fd, /* isWriteable= */ false);
Robert Swiecki437280c2018-01-14 02:09:03 +010066 if (!map) {
Robert Swiecki76f73e12018-01-24 17:07:21 +010067 /* It's not a critical error */
68 return true;
Robert Swieckif8292582018-01-10 16:19:18 +010069 }
Robert Swiecki437280c2018-01-14 02:09:03 +010070 defer {
71 if (munmap(map, fileSz) == -1) {
72 PLOG_W("munmap(%p, %zu)", map, (size_t)fileSz);
73 }
74 close(fd);
75 };
76
Robert Swieckif8292582018-01-10 16:19:18 +010077 if (memmem(map, fileSz, _HF_PERSISTENT_SIG, strlen(_HF_PERSISTENT_SIG))) {
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010078 LOG_I("Persistent signature found in '%s'. Enabling persistent fuzzing mode",
79 hfuzz->exe.cmdline[0]);
80 hfuzz->exe.persistent = true;
Robert Swieckif8292582018-01-10 16:19:18 +010081 }
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010082 if (memmem(map, fileSz, _HF_NETDRIVER_SIG, strlen(_HF_NETDRIVER_SIG))) {
83 LOG_I("NetDriver signature found '%s'", hfuzz->exe.cmdline[0]);
84 hfuzz->exe.netDriver = true;
85 }
86 return true;
Robert Swieckif8292582018-01-10 16:19:18 +010087}
88
Robert Swiecki3ab16642018-01-12 18:08:37 +010089static const char* cmdlineYesNo(bool yes) {
90 return (yes ? "true" : "false");
91}
Robert Swieckia88f96f2015-10-09 16:47:39 +020092
Robert Swieckid50ed422017-11-13 23:32:26 +010093static void cmdlineHelp(const char* pname, struct custom_option* opts) {
Robert Swieckia88f96f2015-10-09 16:47:39 +020094 LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
95 LOG_HELP_BOLD("Options:");
96 for (int i = 0; opts[i].opt.name; i++) {
Robert Swieckif3a5f6a2016-03-16 14:47:30 +010097 if (isprint(opts[i].opt.val) && opts[i].opt.val < 0x80) {
Robert Swiecki0b566112017-10-17 17:39:07 +020098 LOG_HELP_BOLD(" --%s%s%c %s", opts[i].opt.name, "|-", opts[i].opt.val,
Robert Swiecki4e595fb2017-10-11 17:26:51 +020099 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +0200100 } else {
101 LOG_HELP_BOLD(" --%s %s", opts[i].opt.name,
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200102 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +0200103 }
104 LOG_HELP("\t%s", opts[i].descr);
105 }
Jagger32127372015-10-09 23:07:38 +0200106 LOG_HELP_BOLD("\nExamples:");
Robert Swieckid50ed422017-11-13 23:32:26 +0100107 LOG_HELP(
Robert Swieckic39819b2018-01-22 16:09:16 +0100108 " Run the binary over a mutated file chosen from the directory. Disable fuzzing feedback "
109 "(static mode):");
Robert Swiecki216a4362017-12-13 13:02:52 +0100110 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +0200111 LOG_HELP(" As above, provide input over STDIN:");
Robert Swiecki930e12f2017-10-24 14:52:03 +0200112 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -s -- /usr/bin/djpeg");
Robert Swieckic39819b2018-01-22 16:09:16 +0100113 LOG_HELP(" Use compile-time instrumentation (-fsanitize-coverage=trace-pc-guard,...):");
Robert Swiecki216a4362017-12-13 13:02:52 +0100114 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swieckic39819b2018-01-22 16:09:16 +0100115 LOG_HELP(" Use persistent mode w/o instrumentation:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100116 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -P -x -- /usr/bin/djpeg_persistent_mode");
Robert Swiecki98e23372019-01-30 11:50:18 +0100117 LOG_HELP(" Use persistent mode and compile-time (-fsanitize-coverage=trace-pc-guard,...) "
118 "instrumentation:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100119 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -P -- /usr/bin/djpeg_persistent_mode");
Robert Swieckia88f96f2015-10-09 16:47:39 +0200120#if defined(_HF_ARCH_LINUX)
Robert Swiecki930e12f2017-10-24 14:52:03 +0200121 LOG_HELP(
122 " Run the binary with dynamically generate inputs, maximize total no. of instructions:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100123 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_instr -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swiecki930e12f2017-10-24 14:52:03 +0200124 LOG_HELP(" As above, maximize total no. of branches:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100125 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_branch -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swiecki930e12f2017-10-24 14:52:03 +0200126 LOG_HELP(" As above, maximize unique branches (edges) via Intel BTS:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100127 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_bts_edge -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swiecki930e12f2017-10-24 14:52:03 +0200128 LOG_HELP(
129 " As above, maximize unique code blocks via Intel Processor Trace (requires libipt.so):");
Robert Swiecki216a4362017-12-13 13:02:52 +0100130 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ipt_block -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200131#endif /* defined(_HF_ARCH_LINUX) */
Robert Swieckia88f96f2015-10-09 16:47:39 +0200132}
133
Robert Swieckid50ed422017-11-13 23:32:26 +0100134static void cmdlineUsage(const char* pname, struct custom_option* opts) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200135 cmdlineHelp(pname, opts);
136 exit(0);
137}
138
Robert Swiecki15801e82018-11-20 15:59:25 +0100139bool cmdlineAddEnv(honggfuzz_t* hfuzz, char* env) {
140 size_t enveqlen = strlen(env);
141 const char* eqpos = strchr(env, '=');
142 if (eqpos) {
143 enveqlen = (uintptr_t)eqpos - (uintptr_t)env + 1;
144 }
145
146 for (size_t i = 0; i < ARRAYSIZE(hfuzz->exe.envs); i++) {
147 if (hfuzz->exe.envs[i] == NULL) {
148 LOG_D("Adding envar '%s'", env);
149 hfuzz->exe.envs[i] = env;
150 return true;
151 }
152 if (strncmp(hfuzz->exe.envs[i], env, enveqlen) == 0) {
153 LOG_W("Replacing envar '%s' with '%s'", hfuzz->exe.envs[i], env);
154 hfuzz->exe.envs[i] = env;
155 return true;
156 }
157 }
Robert Swiecki68dff9f2018-11-20 16:01:49 +0100158 LOG_E("No more space for new envars (max.%zu)", ARRAYSIZE(hfuzz->exe.envs));
Robert Swiecki15801e82018-11-20 15:59:25 +0100159 return false;
160}
161
Robert Swieckid50ed422017-11-13 23:32:26 +0100162rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200163 struct rlimit cur;
164 if (getrlimit(res, &cur) == -1) {
165 PLOG_F("getrlimit(%d)", res);
166 }
167 if (strcasecmp(optarg, "max") == 0) {
168 return cur.rlim_max;
169 }
170 if (strcasecmp(optarg, "def") == 0) {
171 return cur.rlim_cur;
172 }
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200173 if (util_isANumber(optarg) == false) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200174 LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
175 }
176 rlim_t val = strtoul(optarg, NULL, 0) * mul;
Jagger2bd61b72015-10-10 05:23:32 +0200177 if ((unsigned long)val == ULONG_MAX && errno != 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200178 PLOG_F("strtoul('%s', 0)", optarg);
179 }
180 return val;
181}
182
Robert Swieckia35d9d82017-12-15 22:00:41 +0100183static bool cmdlineVerify(honggfuzz_t* hfuzz) {
Robert Swiecki76f73e12018-01-24 17:07:21 +0100184 if (!cmdlineCheckBinaryType(hfuzz)) {
185 LOG_E("Couldn't test binary for signatures");
186 return false;
187 }
188
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100189 if (!hfuzz->exe.fuzzStdin && !hfuzz->exe.persistent &&
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100190 !checkFor_FILE_PLACEHOLDER(hfuzz->exe.cmdline)) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100191 LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100192 "' if the -s (stdin fuzzing) or --persistent options are not set");
Robert Swieckia35d9d82017-12-15 22:00:41 +0100193 return false;
194 }
195
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100196 if (hfuzz->exe.fuzzStdin && hfuzz->exe.persistent) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100197 LOG_E(
198 "Stdin fuzzing (-s) and persistent fuzzing (-P) cannot be specified at the same time");
199 return false;
200 }
201
202 if (hfuzz->threads.threadsMax >= _HF_THREAD_MAX) {
203 LOG_E("Too many fuzzing threads specified %zu (>= _HF_THREAD_MAX (%u))",
204 hfuzz->threads.threadsMax, _HF_THREAD_MAX);
205 return false;
206 }
207
208 if (strchr(hfuzz->io.fileExtn, '/')) {
209 LOG_E("The file extension contains the '/' character: '%s'", hfuzz->io.fileExtn);
210 return false;
211 }
212
213 if (hfuzz->io.workDir == NULL) {
214 hfuzz->io.workDir = ".";
215 }
216 if (mkdir(hfuzz->io.workDir, 0700) == -1 && errno != EEXIST) {
217 PLOG_E("Couldn't create the workspace directory '%s'", hfuzz->io.workDir);
218 return false;
219 }
220 if (hfuzz->io.crashDir == NULL) {
221 hfuzz->io.crashDir = hfuzz->io.workDir;
222 }
223 if (mkdir(hfuzz->io.crashDir, 0700) && errno != EEXIST) {
224 PLOG_E("Couldn't create the crash directory '%s'", hfuzz->io.crashDir);
225 return false;
226 }
227
Robert Swieckia5b918a2018-03-07 23:59:53 +0100228 if (hfuzz->mutate.mutationsPerRun == 0U && hfuzz->cfg.useVerifier) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100229 LOG_I("Verifier enabled with mutationsPerRun == 0, activating the dry run mode");
230 }
231
Robert Swieckie9231d62018-03-02 03:35:11 +0100232 if (hfuzz->mutate.maxFileSz > _HF_INPUT_MAX_SIZE) {
233 LOG_E("Maximum file size '%zu' bigger than the maximum size '%zu'", hfuzz->mutate.maxFileSz,
Robert Swiecki0a01ea72018-01-11 01:50:18 +0100234 (size_t)_HF_INPUT_MAX_SIZE);
235 return false;
236 }
237
Robert Swieckia35d9d82017-12-15 22:00:41 +0100238 return true;
239}
240
Robert Swieckid50ed422017-11-13 23:32:26 +0100241bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
Robert Swieckicbba70f2018-03-11 03:16:59 +0100242 *hfuzz = (honggfuzz_t){
Robert Swieckia3536a02018-03-08 04:57:51 +0100243 .threads =
244 {
245 .threadsFinished = 0,
Robert Swiecki555e47f2019-02-26 09:03:12 +0100246 .threadsMax = ({
247 long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
248 (ncpus <= 1 ? 1 : ncpus / 2);
249 }),
Robert Swieckia3536a02018-03-08 04:57:51 +0100250 .threadsActiveCnt = 0,
251 .mainThread = pthread_self(),
252 .mainPid = getpid(),
253 },
Robert Swiecki82c707c2017-11-14 16:36:23 +0100254 .io =
255 {
256 .inputDir = NULL,
Robert Swieckia35d9d82017-12-15 22:00:41 +0100257 .inputDirPtr = NULL,
Robert Swiecki82c707c2017-11-14 16:36:23 +0100258 .fileCnt = 0,
259 .fileCntDone = false,
260 .fileExtn = "fuzz",
Robert Swieckiced3eba2017-12-15 15:33:03 +0100261 .workDir = NULL,
262 .crashDir = NULL,
263 .covDirAll = NULL,
264 .covDirNew = NULL,
Robert Swiecki26fd6d52017-11-15 00:46:21 +0100265 .saveUnique = true,
Robert Swiecki363510f2018-03-09 02:00:30 +0100266 .dynfileqCnt = 0U,
267 .dynfileq_mutex = PTHREAD_RWLOCK_INITIALIZER,
Robert Swiecki82c707c2017-11-14 16:36:23 +0100268 },
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100269 .exe =
270 {
Robert Swiecki2aeff252018-01-10 14:58:44 +0100271 .argc = 0,
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100272 .cmdline = NULL,
273 .nullifyStdio = true,
274 .fuzzStdin = false,
275 .externalCommand = NULL,
276 .postExternalCommand = NULL,
arnow117c7566f62019-04-09 05:14:11 +0800277 .feedbackMutateCommand = NULL,
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100278 .persistent = false,
279 .netDriver = false,
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100280 .asLimit = 0U,
281 .rssLimit = 0U,
282 .dataLimit = 0U,
283 .clearEnv = false,
Robert Swiecki15801e82018-11-20 15:59:25 +0100284 .envs = {},
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100285 },
Robert Swiecki371e1292017-12-18 01:10:33 +0100286 .timing =
287 {
288 .timeStart = time(NULL),
289 .runEndTime = 0,
290 .tmOut = 10,
Robert Swieckieba27172017-12-18 01:12:02 +0100291 .tmoutVTALRM = false,
Robert Swiecki36f7e512018-01-16 03:46:41 +0100292 .lastCovUpdate = time(NULL),
Robert Swiecki371e1292017-12-18 01:10:33 +0100293 },
Robert Swiecki04dcac32018-03-02 03:05:26 +0100294 .mutate =
295 {
296 .mutationsMax = 0,
297 .dictionaryFile = NULL,
298 .dictionaryCnt = 0,
299 .mutationsPerRun = 6U,
Robert Swieckie9231d62018-03-02 03:35:11 +0100300 .maxFileSz = 0UL,
Robert Swiecki04dcac32018-03-02 03:05:26 +0100301 },
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100302 .display =
303 {
304 .useScreen = true,
Robert Swieckieb9fbdd2018-03-08 05:15:37 +0100305 .lastDisplayMillis = util_timeNowMillis(),
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100306 .cmdline_txt[0] = '\0',
307 },
Robert Swieckia5b918a2018-03-07 23:59:53 +0100308 .cfg =
309 {
310 .useVerifier = false,
311 .exitUponCrash = false,
312 .report_mutex = PTHREAD_MUTEX_INITIALIZER,
313 .reportFile = NULL,
314 .dynFileIterExpire = 0,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200315#if defined(__ANDROID__)
Robert Swieckia5b918a2018-03-07 23:59:53 +0100316 .monitorSIGABRT = false,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200317#else
Robert Swieckia5b918a2018-03-07 23:59:53 +0100318 .monitorSIGABRT = true,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200319#endif
plusun99ef77e2018-07-31 10:52:27 +0000320 .only_printable = false,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100321 },
322 .sanitizer =
323 {
324 .enable = false,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100325 },
Robert Swieckia5b918a2018-03-07 23:59:53 +0100326 .feedback =
327 {
328 .feedbackMap = NULL,
329 .feedback_mutex = PTHREAD_MUTEX_INITIALIZER,
330 .bbFd = -1,
331 .blacklistFile = NULL,
332 .blacklist = NULL,
333 .blacklistCnt = 0,
334 .skipFeedbackOnTimeout = false,
335 .dynFileMethod = _HF_DYNFILE_SOFT,
Robert Swiecki363510f2018-03-09 02:00:30 +0100336 .state = _HF_STATE_UNSET,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100337 },
Robert Swiecki01a980e2017-11-14 03:36:50 +0100338 .cnts =
339 {
340 .mutationsCnt = 0,
341 .crashesCnt = 0,
342 .uniqueCrashesCnt = 0,
343 .verifiedCrashesCnt = 0,
344 .blCrashesCnt = 0,
345 .timeoutedCnt = 0,
346 },
Robert Swieckia3536a02018-03-08 04:57:51 +0100347 .socketFuzzer =
348 {
349 .enabled = false,
350 .serverSocket = -1,
351 .clientSocket = -1,
352 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200353
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100354 /* Linux code */
Robert Swieckid50ed422017-11-13 23:32:26 +0100355 .linux =
356 {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200357 .exeFd = -1,
Robert Swieckid50ed422017-11-13 23:32:26 +0100358 .hwCnts =
359 {
360 .cpuInstrCnt = 0ULL,
361 .cpuBranchCnt = 0ULL,
362 .bbCnt = 0ULL,
363 .newBBCnt = 0ULL,
364 .softCntPc = 0ULL,
365 .softCntCmp = 0ULL,
366 },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200367 .dynamicCutOffAddr = ~(0ULL),
368 .disableRandomization = true,
369 .ignoreAddr = NULL,
370 .numMajorFrames = 7,
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200371 .symsBlFile = NULL,
372 .symsBlCnt = 0,
373 .symsBl = NULL,
374 .symsWlFile = NULL,
375 .symsWlCnt = 0,
376 .symsWl = NULL,
377 .cloneFlags = 0,
378 .kernelOnly = false,
379 .useClone = true,
Jaggerab26e702016-03-22 04:28:00 +0100380 },
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200381 /* NetBSD code */
382 .netbsd =
383 {
384 .ignoreAddr = NULL,
385 .numMajorFrames = 7,
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200386 .symsBlFile = NULL,
387 .symsBlCnt = 0,
388 .symsBl = NULL,
389 .symsWlFile = NULL,
390 .symsWlCnt = 0,
391 .symsWl = NULL,
392 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200393 };
Robert Swieckia88f96f2015-10-09 16:47:39 +0200394
Robert Swiecki363510f2018-03-09 02:00:30 +0100395 TAILQ_INIT(&hfuzz->io.dynfileq);
Robert Swiecki04dcac32018-03-02 03:05:26 +0100396 TAILQ_INIT(&hfuzz->mutate.dictq);
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100397
Robert Swiecki0b566112017-10-17 17:39:07 +0200398 // clang-format off
Robert Swieckia88f96f2015-10-09 16:47:39 +0200399 struct custom_option custom_opts[] = {
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200400 { { "help", no_argument, NULL, 'h' }, "Help plz.." },
401 { { "input", required_argument, NULL, 'f' }, "Path to a directory containing initial file corpus" },
Robert Swieckie46d8af2018-01-12 03:20:04 +0100402 { { "persistent", no_argument, NULL, 'P' }, "Enable persistent fuzzing (use hfuzz_cc/hfuzz-clang to compile code). This will be auto-detected!!!" },
Robert Swiecki930e12f2017-10-24 14:52:03 +0200403 { { "instrument", no_argument, NULL, 'z' }, "*DEFAULT-MODE-BY-DEFAULT* Enable compile-time instrumentation (use hfuzz_cc/hfuzz-clang to compile code)" },
Robert Swiecki6edfd6c2018-01-22 16:06:53 +0100404 { { "noinst", no_argument, NULL, 'x' }, "Static mode only, disable any instrumentation (hw/sw) feedback" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200405 { { "keep_output", no_argument, NULL, 'Q' }, "Don't close children's stdin, stdout, stderr; can be noisy" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100406 { { "timeout", required_argument, NULL, 't' }, "Timeout in seconds (default: 10)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200407 { { "threads", required_argument, NULL, 'n' }, "Number of concurrent fuzzing threads (default: number of CPUs / 2)" },
408 { { "stdin_input", no_argument, NULL, 's' }, "Provide fuzzing input on STDIN, instead of ___FILE___" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100409 { { "mutations_per_run", required_argument, NULL, 'r' }, "Maximal number of mutations per one run (default: 6)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200410 { { "logfile", required_argument, NULL, 'l' }, "Log file" },
411 { { "verbose", no_argument, NULL, 'v' }, "Disable ANSI console; use simple log output" },
412 { { "verifier", no_argument, NULL, 'V' }, "Enable crashes verifier" },
Robert Swiecki97cd6242017-12-27 21:02:47 +0100413 { { "debug", no_argument, NULL, 'd' }, "Show debug messages (level >= 4)" },
414 { { "quiet", no_argument, NULL, 'q' }, "Show only warnings and more serious messages (level <= 1)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200415 { { "extension", required_argument, NULL, 'e' }, "Input file extension (e.g. 'swf'), (default: 'fuzz')" },
416 { { "workspace", required_argument, NULL, 'W' }, "Workspace directory to save crashes & runtime files (default: '.')" },
Robert Swieckia35d9d82017-12-15 22:00:41 +0100417 { { "crashdir", required_argument, NULL, 0x600 }, "Directory where crashes are saved to (default: workspace directory)" },
418 { { "covdir_all", required_argument, NULL, 0x601 }, "Coverage is written to a separate directory (default: input directory)" },
419 { { "covdir_new", required_argument, NULL, 0x602 }, "New coverage (beyond the dry-run fuzzing phase) is written to this separate directory" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200420 { { "dict", required_argument, NULL, 'w' }, "Dictionary file. Format:http://llvm.org/docs/LibFuzzer.html#dictionaries" },
421 { { "stackhash_bl", required_argument, NULL, 'B' }, "Stackhashes blacklist file (one entry per line)" },
422 { { "mutate_cmd", required_argument, NULL, 'c' }, "External command producing fuzz files (instead of internal mutators)" },
423 { { "pprocess_cmd", required_argument, NULL, 0x104 }, "External command postprocessing files produced by internal mutators" },
arnow117c7566f62019-04-09 05:14:11 +0800424 { { "ffmutate_cmd", required_argument, NULL, 0x110 }, "External command mutating files which have effective coverage feedback" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100425 { { "run_time", required_argument, NULL, 0x109 }, "Number of seconds this fuzzing session will last (default: 0 [no limit])" },
426 { { "iterations", required_argument, NULL, 'N' }, "Number of fuzzing iterations (default: 0 [no limit])" },
427 { { "rlimit_as", required_argument, NULL, 0x100 }, "Per process RLIMIT_AS in MiB (default: 0 [no limit])" },
428 { { "rlimit_rss", required_argument, NULL, 0x101 }, "Per process RLIMIT_RSS in MiB (default: 0 [no limit]). It will also set *SAN's soft_rss_limit_mb if used" },
429 { { "rlimit_data", required_argument, NULL, 0x102 }, "Per process RLIMIT_DATA in MiB (default: 0 [no limit])" },
Robert Swieckic58ca512018-11-06 17:50:37 +0100430 { { "rlimit_core", required_argument, NULL, 0x103 }, "Per process RLIMIT_CORE in MiB (default: 0 [no cores are produced])" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100431 { { "report", required_argument, NULL, 'R' }, "Write report to this file (default: '<workdir>/" _HF_REPORT_FILE "')" },
432 { { "max_file_size", required_argument, NULL, 'F' }, "Maximal size of files processed by the fuzzer in bytes (default: 1048576)" },
Robert Swiecki8954afd2017-11-14 18:14:22 +0100433 { { "clear_env", no_argument, NULL, 0x108 }, "Clear all environment variables before executing the binary" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200434 { { "env", required_argument, NULL, 'E' }, "Pass this environment variable, can be used multiple times" },
435 { { "save_all", no_argument, NULL, 'u' }, "Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames" },
436 { { "tmout_sigvtalrm", no_argument, NULL, 'T' }, "Use SIGVTALRM to kill timeouting processes (default: use SIGKILL)" },
437 { { "sanitizers", no_argument, NULL, 'S' }, "Enable sanitizers settings (default: false)" },
Robert Swieckib1f5a252018-01-22 16:05:39 +0100438 { { "monitor_sigabrt", required_argument, NULL, 0x105 }, "Monitor SIGABRT (default: false for Android, true for other platforms)" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100439 { { "no_fb_timeout", required_argument, NULL, 0x106 }, "Skip feedback if the process has timeouted (default: false)" },
440 { { "exit_upon_crash", no_argument, NULL, 0x107 }, "Exit upon seeing the first crash (default: false)" },
Robert Swiecki642c7fb2018-11-12 14:46:16 +0100441 { { "socket_fuzzer", no_argument, NULL, 0x10B }, "Instrument external fuzzer via socket" },
442 { { "netdriver", no_argument, NULL, 0x10C }, "Use netdriver (libhfnetdriver/). In most cases it will be autodetected through a binary signature" },
plusun99ef77e2018-07-31 10:52:27 +0000443 { { "only_printable", no_argument, NULL, 'o' }, "Only generate printable inputs" },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200444
445#if defined(_HF_ARCH_LINUX)
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200446 { { "linux_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
447 { { "linux_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100448 { { "linux_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: 0)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200449 { { "linux_keep_aslr", no_argument, NULL, 0x501 }, "Don't disable ASLR randomization, might be useful with MSAN" },
450 { { "linux_perf_ignore_above", required_argument, NULL, 0x503 }, "Ignore perf events which report IPs above this address" },
451 { { "linux_perf_instr", no_argument, NULL, 0x510 }, "Use PERF_COUNT_HW_INSTRUCTIONS perf" },
452 { { "linux_perf_branch", no_argument, NULL, 0x511 }, "Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf" },
453 { { "linux_perf_bts_edge", no_argument, NULL, 0x513 }, "Use Intel BTS to count unique edges" },
454 { { "linux_perf_ipt_block", no_argument, NULL, 0x514 }, "Use Intel Processor Trace to count unique blocks (requires libipt.so)" },
455 { { "linux_perf_kernel_only", no_argument, NULL, 0x515 }, "Gather kernel-only coverage with Intel PT and with Intel BTS" },
456 { { "linux_ns_net", no_argument, NULL, 0x0530 }, "Use Linux NET namespace isolation" },
457 { { "linux_ns_pid", no_argument, NULL, 0x0531 }, "Use Linux PID namespace isolation" },
458 { { "linux_ns_ipc", no_argument, NULL, 0x0532 }, "Use Linux IPC namespace isolation" },
459#endif // defined(_HF_ARCH_LINUX)
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200460
461#if defined(_HF_ARCH_NETBSD)
462 { { "netbsd_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
463 { { "netbsd_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200464 { { "netbsd_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: 0)" },
465#endif // defined(_HF_ARCH_NETBSD)
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200466 { { 0, 0, 0, 0 }, NULL },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200467 };
Robert Swiecki0b566112017-10-17 17:39:07 +0200468 // clang-format on
Robert Swieckia88f96f2015-10-09 16:47:39 +0200469
470 struct option opts[ARRAYSIZE(custom_opts)];
471 for (unsigned i = 0; i < ARRAYSIZE(custom_opts); i++) {
472 opts[i] = custom_opts[i].opt;
473 }
474
475 enum llevel_t ll = INFO;
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200476 const char* logfile = NULL;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200477 int opt_index = 0;
478 for (;;) {
Robert Swiecki0b566112017-10-17 17:39:07 +0200479 int c = getopt_long(
Robert Swiecki8267c772018-08-23 23:21:40 +0200480 argc, argv, "-?hQvVsuPxf:dqe:W:r:c:F:t:R:n:N:l:p:g:E:w:B:zTSo", opts, &opt_index);
Robert Swieckid50ed422017-11-13 23:32:26 +0100481 if (c < 0) break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200482
483 switch (c) {
Robert Swieckid50ed422017-11-13 23:32:26 +0100484 case 'h':
485 case '?':
486 cmdlineUsage(argv[0], custom_opts);
487 break;
488 case 'f':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100489 hfuzz->io.inputDir = optarg;
Robert Swieckiced3eba2017-12-15 15:33:03 +0100490 if (hfuzz->io.covDirAll == NULL) {
491 hfuzz->io.covDirAll = optarg;
492 }
Robert Swieckid50ed422017-11-13 23:32:26 +0100493 break;
494 case 'x':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100495 hfuzz->feedback.dynFileMethod = _HF_DYNFILE_NONE;
Robert Swieckid50ed422017-11-13 23:32:26 +0100496 break;
497 case 'Q':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100498 hfuzz->exe.nullifyStdio = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100499 break;
500 case 'v':
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100501 hfuzz->display.useScreen = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100502 break;
503 case 'V':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100504 hfuzz->cfg.useVerifier = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100505 break;
506 case 's':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100507 hfuzz->exe.fuzzStdin = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100508 break;
509 case 'u':
Robert Swiecki26fd6d52017-11-15 00:46:21 +0100510 hfuzz->io.saveUnique = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100511 break;
512 case 'l':
513 logfile = optarg;
514 break;
515 case 'd':
Robert Swiecki97cd6242017-12-27 21:02:47 +0100516 ll = DEBUG;
517 break;
518 case 'q':
519 ll = WARNING;
Robert Swieckid50ed422017-11-13 23:32:26 +0100520 break;
521 case 'e':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100522 hfuzz->io.fileExtn = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100523 break;
524 case 'W':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100525 hfuzz->io.workDir = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100526 break;
Robert Swieckia35d9d82017-12-15 22:00:41 +0100527 case 0x600:
Robert Swieckiced3eba2017-12-15 15:33:03 +0100528 hfuzz->io.crashDir = optarg;
529 break;
Robert Swieckia35d9d82017-12-15 22:00:41 +0100530 case 0x601:
531 hfuzz->io.covDirAll = optarg;
532 break;
533 case 0x602:
534 hfuzz->io.covDirNew = optarg;
535 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100536 case 'r':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100537 hfuzz->mutate.mutationsPerRun = strtoul(optarg, NULL, 10);
Robert Swieckid50ed422017-11-13 23:32:26 +0100538 break;
539 case 'c':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100540 hfuzz->exe.externalCommand = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100541 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100542 case 'S':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100543 hfuzz->sanitizer.enable = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100544 break;
dobinedf9f8d2018-01-21 13:57:02 +0100545 case 0x10B:
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100546 hfuzz->socketFuzzer.enabled = true;
Robert Swiecki56276192018-01-21 15:43:02 +0100547 hfuzz->timing.tmOut = 0; // Disable process timeout checks
dobinedf9f8d2018-01-21 13:57:02 +0100548 break;
Robert Swiecki642c7fb2018-11-12 14:46:16 +0100549 case 0x10C:
550 hfuzz->exe.netDriver = true;
551 break;
plusun99ef77e2018-07-31 10:52:27 +0000552 case 'o':
553 hfuzz->cfg.only_printable = true;
554 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100555 case 'z':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100556 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_SOFT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100557 break;
558 case 'F':
Robert Swieckie9231d62018-03-02 03:35:11 +0100559 hfuzz->mutate.maxFileSz = strtoul(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100560 break;
561 case 't':
Robert Swiecki371e1292017-12-18 01:10:33 +0100562 hfuzz->timing.tmOut = atol(optarg);
Robert Swieckid50ed422017-11-13 23:32:26 +0100563 break;
564 case 'R':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100565 hfuzz->cfg.reportFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100566 break;
567 case 'n':
Robert Swiecki555e47f2019-02-26 09:03:12 +0100568 if (optarg[0] == 'a') {
569 long ncpus = sysconf(_SC_NPROCESSORS_ONLN);
570 hfuzz->threads.threadsMax = (ncpus < 1 ? 1 : ncpus);
571 } else {
572 hfuzz->threads.threadsMax = atol(optarg);
573 }
Robert Swieckid50ed422017-11-13 23:32:26 +0100574 break;
575 case 0x109: {
576 time_t p = atol(optarg);
577 if (p > 0) {
Robert Swiecki371e1292017-12-18 01:10:33 +0100578 hfuzz->timing.runEndTime = time(NULL) + p;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200579 }
Robert Swieckid50ed422017-11-13 23:32:26 +0100580 } break;
581 case 'N':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100582 hfuzz->mutate.mutationsMax = atol(optarg);
Robert Swieckid50ed422017-11-13 23:32:26 +0100583 break;
584 case 0x100:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100585 hfuzz->exe.asLimit = strtoull(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100586 break;
587 case 0x101:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100588 hfuzz->exe.rssLimit = strtoull(optarg, NULL, 0);
Robert Swiecki8954afd2017-11-14 18:14:22 +0100589 break;
590 case 0x102:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100591 hfuzz->exe.dataLimit = strtoull(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100592 break;
Robert Swieckic58ca512018-11-06 17:50:37 +0100593 case 0x103:
594 hfuzz->exe.coreLimit = strtoull(optarg, NULL, 0);
595 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100596 case 0x104:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100597 hfuzz->exe.postExternalCommand = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100598 break;
arnow117c7566f62019-04-09 05:14:11 +0800599 case 0x110:
600 hfuzz->exe.feedbackMutateCommand = optarg;
Robert Swiecki251ee7c2019-04-17 21:56:22 +0200601 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100602 case 0x105:
603 if ((strcasecmp(optarg, "0") == 0) || (strcasecmp(optarg, "false") == 0)) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100604 hfuzz->cfg.monitorSIGABRT = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100605 } else {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100606 hfuzz->cfg.monitorSIGABRT = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100607 }
608 break;
609 case 0x106:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100610 hfuzz->feedback.skipFeedbackOnTimeout = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100611 break;
612 case 0x107:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100613 hfuzz->cfg.exitUponCrash = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100614 break;
Robert Swiecki8954afd2017-11-14 18:14:22 +0100615 case 0x108:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100616 hfuzz->exe.clearEnv = true;
Robert Swiecki8954afd2017-11-14 18:14:22 +0100617 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100618 case 'P':
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100619 hfuzz->exe.persistent = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100620 break;
621 case 'T':
Robert Swieckieba27172017-12-18 01:12:02 +0100622 hfuzz->timing.tmoutVTALRM = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100623 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100624 case 'E':
Robert Swiecki15801e82018-11-20 15:59:25 +0100625 if (!cmdlineAddEnv(hfuzz, optarg)) {
626 return false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100627 }
628 break;
629 case 'w':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100630 hfuzz->mutate.dictionaryFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100631 break;
632 case 'B':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100633 hfuzz->feedback.blacklistFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100634 break;
Robert Swiecki846ccd72017-01-12 17:52:23 +0100635#if defined(_HF_ARCH_LINUX)
Robert Swieckid50ed422017-11-13 23:32:26 +0100636 case 0x500:
637 hfuzz->linux.ignoreAddr = (void*)strtoul(optarg, NULL, 0);
638 break;
639 case 0x501:
640 hfuzz->linux.disableRandomization = false;
641 break;
642 case 0x503:
643 hfuzz->linux.dynamicCutOffAddr = strtoull(optarg, NULL, 0);
644 break;
645 case 0x504:
646 hfuzz->linux.symsBlFile = optarg;
647 break;
648 case 0x505:
649 hfuzz->linux.symsWlFile = optarg;
650 break;
651 case 0x510:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100652 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100653 break;
654 case 0x511:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100655 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100656 break;
657 case 0x513:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100658 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
Robert Swieckid50ed422017-11-13 23:32:26 +0100659 break;
660 case 0x514:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100661 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
Robert Swieckid50ed422017-11-13 23:32:26 +0100662 break;
663 case 0x515:
664 hfuzz->linux.kernelOnly = true;
665 break;
666 case 0x530:
667 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWNET);
668 break;
669 case 0x531:
670 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWPID);
671 break;
672 case 0x532:
673 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWIPC);
674 break;
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200675#endif /* defined(_HF_ARCH_LINUX) */
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200676#if defined(_HF_ARCH_NETBSD)
677 case 0x500:
678 hfuzz->netbsd.ignoreAddr = (void*)strtoul(optarg, NULL, 0);
679 break;
680 case 0x504:
681 hfuzz->netbsd.symsBlFile = optarg;
682 break;
683 case 0x505:
684 hfuzz->netbsd.symsWlFile = optarg;
685 break;
686#endif /* defined(_HF_ARCH_NETBSD) */
Robert Swieckid50ed422017-11-13 23:32:26 +0100687 default:
688 cmdlineUsage(argv[0], custom_opts);
689 return false;
690 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200691 }
692 }
Jagger72f258b2015-10-09 23:09:01 +0200693
Robert Swiecki44894272019-01-30 12:53:54 +0100694 logInitLogFile(logfile, -1, ll);
695
Robert Swiecki2aeff252018-01-10 14:58:44 +0100696 hfuzz->exe.argc = argc - optind;
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100697 hfuzz->exe.cmdline = (const char* const*)&argv[optind];
Robert Swiecki2aeff252018-01-10 14:58:44 +0100698 if (hfuzz->exe.argc <= 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200699 LOG_E("No fuzz command provided");
700 cmdlineUsage(argv[0], custom_opts);
701 return false;
702 }
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100703 if (!files_exists(hfuzz->exe.cmdline[0])) {
704 LOG_E("Your fuzzed binary '%s' doesn't seem to exist", hfuzz->exe.cmdline[0]);
705 return false;
706 }
Robert Swieckia35d9d82017-12-15 22:00:41 +0100707 if (!cmdlineVerify(hfuzz)) {
Anestis Bechtsoudisc1a0d9f2016-12-29 11:34:10 +0200708 return false;
709 }
710
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100711 display_createTargetStr(hfuzz);
712
Robert Swieckic49b96b2019-02-12 08:29:11 +0100713 sigemptyset(&hfuzz->exe.waitSigSet);
714 sigaddset(&hfuzz->exe.waitSigSet, SIGIO); /* Persistent socket data */
Robert Swiecki64d52432019-02-14 23:02:13 +0100715 sigaddset(&hfuzz->exe.waitSigSet, SIGUSR1); /* Ping from the signal thread */
Robert Swieckic49b96b2019-02-12 08:29:11 +0100716
Robert Swiecki98e23372019-01-30 11:50:18 +0100717 LOG_I("cmdline:'%s', bin:'%s' inputDir:'%s', fuzzStdin:%s, mutationsPerRun:%u, "
718 "externalCommand:'%s', timeout:%ld, mutationsMax:%zu, threadsMax:%zu",
719 hfuzz->display.cmdline_txt, hfuzz->exe.cmdline[0], hfuzz->io.inputDir,
720 cmdlineYesNo(hfuzz->exe.fuzzStdin), hfuzz->mutate.mutationsPerRun,
721 !hfuzz->exe.externalCommand ? "" : hfuzz->exe.externalCommand, (long)hfuzz->timing.tmOut,
722 hfuzz->mutate.mutationsMax, hfuzz->threads.threadsMax);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200723
Robert Swieckia88f96f2015-10-09 16:47:39 +0200724 return true;
725}