blob: b177ab3e62a4d1d8dc92b9476a53e06a1f555353 [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 Swieckia88f96f2015-10-09 16:47:39 +020034#include <stdio.h>
Robert Swieckid0fa62c2017-09-28 18:11:05 +020035#include <stdlib.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020036#include <string.h>
Robert Swieckif8292582018-01-10 16:19:18 +010037#include <sys/mman.h>
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010038#include <sys/queue.h>
Robert Swieckia35d9d82017-12-15 22:00:41 +010039#include <sys/stat.h>
40#include <sys/types.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020041#include <unistd.h>
42
Robert Swiecki8a1fc672018-01-25 23:22:47 +010043#include "display.h"
Robert Swiecki246af3e2018-01-05 14:56:32 +010044#include "libhfcommon/common.h"
45#include "libhfcommon/files.h"
46#include "libhfcommon/log.h"
47#include "libhfcommon/util.h"
Robert Swieckia88f96f2015-10-09 16:47:39 +020048
49struct custom_option {
50 struct option opt;
Robert Swiecki4e595fb2017-10-11 17:26:51 +020051 const char* descr;
Robert Swieckia88f96f2015-10-09 16:47:39 +020052};
53
Robert Swiecki97d0cee2017-12-18 00:17:50 +010054static bool checkFor_FILE_PLACEHOLDER(const char* const* args) {
Robert Swieckia88f96f2015-10-09 16:47:39 +020055 for (int x = 0; args[x]; x++) {
Robert Swieckid50ed422017-11-13 23:32:26 +010056 if (strstr(args[x], _HF_FILE_PLACEHOLDER)) return true;
Robert Swieckia88f96f2015-10-09 16:47:39 +020057 }
58 return false;
59}
60
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010061static bool cmdlineCheckBinaryType(honggfuzz_t* hfuzz) {
Robert Swieckif8292582018-01-10 16:19:18 +010062 int fd;
63 off_t fileSz;
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010064 uint8_t* map = files_mapFile(hfuzz->exe.cmdline[0], &fileSz, &fd, /* isWriteable= */ false);
Robert Swiecki437280c2018-01-14 02:09:03 +010065 if (!map) {
Robert Swiecki76f73e12018-01-24 17:07:21 +010066 /* It's not a critical error */
67 return true;
Robert Swieckif8292582018-01-10 16:19:18 +010068 }
Robert Swiecki437280c2018-01-14 02:09:03 +010069 defer {
70 if (munmap(map, fileSz) == -1) {
71 PLOG_W("munmap(%p, %zu)", map, (size_t)fileSz);
72 }
73 close(fd);
74 };
75
Robert Swieckif8292582018-01-10 16:19:18 +010076 if (memmem(map, fileSz, _HF_PERSISTENT_SIG, strlen(_HF_PERSISTENT_SIG))) {
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010077 LOG_I("Persistent signature found in '%s'. Enabling persistent fuzzing mode",
78 hfuzz->exe.cmdline[0]);
79 hfuzz->exe.persistent = true;
Robert Swieckif8292582018-01-10 16:19:18 +010080 }
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +010081 if (memmem(map, fileSz, _HF_NETDRIVER_SIG, strlen(_HF_NETDRIVER_SIG))) {
82 LOG_I("NetDriver signature found '%s'", hfuzz->exe.cmdline[0]);
83 hfuzz->exe.netDriver = true;
84 }
85 return true;
Robert Swieckif8292582018-01-10 16:19:18 +010086}
87
Robert Swiecki3ab16642018-01-12 18:08:37 +010088static const char* cmdlineYesNo(bool yes) {
89 return (yes ? "true" : "false");
90}
Robert Swieckia88f96f2015-10-09 16:47:39 +020091
Robert Swieckid50ed422017-11-13 23:32:26 +010092static void cmdlineHelp(const char* pname, struct custom_option* opts) {
Robert Swieckia88f96f2015-10-09 16:47:39 +020093 LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
94 LOG_HELP_BOLD("Options:");
95 for (int i = 0; opts[i].opt.name; i++) {
Robert Swieckif3a5f6a2016-03-16 14:47:30 +010096 if (isprint(opts[i].opt.val) && opts[i].opt.val < 0x80) {
Robert Swiecki0b566112017-10-17 17:39:07 +020097 LOG_HELP_BOLD(" --%s%s%c %s", opts[i].opt.name, "|-", opts[i].opt.val,
Robert Swiecki4e595fb2017-10-11 17:26:51 +020098 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +020099 } else {
100 LOG_HELP_BOLD(" --%s %s", opts[i].opt.name,
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200101 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +0200102 }
103 LOG_HELP("\t%s", opts[i].descr);
104 }
Jagger32127372015-10-09 23:07:38 +0200105 LOG_HELP_BOLD("\nExamples:");
Robert Swieckid50ed422017-11-13 23:32:26 +0100106 LOG_HELP(
Robert Swieckic39819b2018-01-22 16:09:16 +0100107 " Run the binary over a mutated file chosen from the directory. Disable fuzzing feedback "
108 "(static mode):");
Robert Swiecki216a4362017-12-13 13:02:52 +0100109 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +0200110 LOG_HELP(" As above, provide input over STDIN:");
Robert Swiecki930e12f2017-10-24 14:52:03 +0200111 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -s -- /usr/bin/djpeg");
Robert Swieckic39819b2018-01-22 16:09:16 +0100112 LOG_HELP(" Use compile-time instrumentation (-fsanitize-coverage=trace-pc-guard,...):");
Robert Swiecki216a4362017-12-13 13:02:52 +0100113 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
Robert Swieckic39819b2018-01-22 16:09:16 +0100114 LOG_HELP(" Use persistent mode w/o instrumentation:");
Robert Swiecki216a4362017-12-13 13:02:52 +0100115 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -P -x -- /usr/bin/djpeg_persistent_mode");
Robert Swieckic39819b2018-01-22 16:09:16 +0100116 LOG_HELP(
117 " 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 Swieckid50ed422017-11-13 23:32:26 +0100139rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200140 struct rlimit cur;
141 if (getrlimit(res, &cur) == -1) {
142 PLOG_F("getrlimit(%d)", res);
143 }
144 if (strcasecmp(optarg, "max") == 0) {
145 return cur.rlim_max;
146 }
147 if (strcasecmp(optarg, "def") == 0) {
148 return cur.rlim_cur;
149 }
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200150 if (util_isANumber(optarg) == false) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200151 LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
152 }
153 rlim_t val = strtoul(optarg, NULL, 0) * mul;
Jagger2bd61b72015-10-10 05:23:32 +0200154 if ((unsigned long)val == ULONG_MAX && errno != 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200155 PLOG_F("strtoul('%s', 0)", optarg);
156 }
157 return val;
158}
159
Robert Swieckia35d9d82017-12-15 22:00:41 +0100160static bool cmdlineVerify(honggfuzz_t* hfuzz) {
Robert Swiecki76f73e12018-01-24 17:07:21 +0100161 if (!cmdlineCheckBinaryType(hfuzz)) {
162 LOG_E("Couldn't test binary for signatures");
163 return false;
164 }
165
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100166 if (!hfuzz->exe.fuzzStdin && !hfuzz->exe.persistent &&
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100167 !checkFor_FILE_PLACEHOLDER(hfuzz->exe.cmdline)) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100168 LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100169 "' if the -s (stdin fuzzing) or --persistent options are not set");
Robert Swieckia35d9d82017-12-15 22:00:41 +0100170 return false;
171 }
172
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100173 if (hfuzz->exe.fuzzStdin && hfuzz->exe.persistent) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100174 LOG_E(
175 "Stdin fuzzing (-s) and persistent fuzzing (-P) cannot be specified at the same time");
176 return false;
177 }
178
179 if (hfuzz->threads.threadsMax >= _HF_THREAD_MAX) {
180 LOG_E("Too many fuzzing threads specified %zu (>= _HF_THREAD_MAX (%u))",
181 hfuzz->threads.threadsMax, _HF_THREAD_MAX);
182 return false;
183 }
184
185 if (strchr(hfuzz->io.fileExtn, '/')) {
186 LOG_E("The file extension contains the '/' character: '%s'", hfuzz->io.fileExtn);
187 return false;
188 }
189
190 if (hfuzz->io.workDir == NULL) {
191 hfuzz->io.workDir = ".";
192 }
193 if (mkdir(hfuzz->io.workDir, 0700) == -1 && errno != EEXIST) {
194 PLOG_E("Couldn't create the workspace directory '%s'", hfuzz->io.workDir);
195 return false;
196 }
197 if (hfuzz->io.crashDir == NULL) {
198 hfuzz->io.crashDir = hfuzz->io.workDir;
199 }
200 if (mkdir(hfuzz->io.crashDir, 0700) && errno != EEXIST) {
201 PLOG_E("Couldn't create the crash directory '%s'", hfuzz->io.crashDir);
202 return false;
203 }
204
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200205#if defined(_HF_ARCH_LINUX)
Robert Swieckia35d9d82017-12-15 22:00:41 +0100206 if (hfuzz->linux.pid > 0 || hfuzz->linux.pidFile) {
207 LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1",
208 hfuzz->linux.pid);
209 hfuzz->threads.threadsMax = 1;
210 }
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200211#elif defined(_HF_ARCH_NETBSD)
212 if (hfuzz->netbsd.pid > 0 || hfuzz->netbsd.pidFile) {
213 LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1",
214 hfuzz->netbsd.pid);
215 hfuzz->threads.threadsMax = 1;
216 }
217#endif
Robert Swieckia35d9d82017-12-15 22:00:41 +0100218
Robert Swieckia5b918a2018-03-07 23:59:53 +0100219 if (hfuzz->mutate.mutationsPerRun == 0U && hfuzz->cfg.useVerifier) {
Robert Swieckia35d9d82017-12-15 22:00:41 +0100220 LOG_I("Verifier enabled with mutationsPerRun == 0, activating the dry run mode");
221 }
222
Robert Swieckie9231d62018-03-02 03:35:11 +0100223 if (hfuzz->mutate.maxFileSz > _HF_INPUT_MAX_SIZE) {
224 LOG_E("Maximum file size '%zu' bigger than the maximum size '%zu'", hfuzz->mutate.maxFileSz,
Robert Swiecki0a01ea72018-01-11 01:50:18 +0100225 (size_t)_HF_INPUT_MAX_SIZE);
226 return false;
227 }
228
Robert Swieckia35d9d82017-12-15 22:00:41 +0100229 return true;
230}
231
Robert Swieckid50ed422017-11-13 23:32:26 +0100232bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
Robert Swieckicbba70f2018-03-11 03:16:59 +0100233 *hfuzz = (honggfuzz_t){
Robert Swieckia3536a02018-03-08 04:57:51 +0100234 .threads =
235 {
236 .threadsFinished = 0,
237 .threadsMax =
238 (sysconf(_SC_NPROCESSORS_ONLN) <= 1) ? 1 : sysconf(_SC_NPROCESSORS_ONLN) / 2,
239 .threadsActiveCnt = 0,
240 .mainThread = pthread_self(),
241 .mainPid = getpid(),
242 },
Robert Swiecki82c707c2017-11-14 16:36:23 +0100243 .io =
244 {
245 .inputDir = NULL,
Robert Swieckia35d9d82017-12-15 22:00:41 +0100246 .inputDirPtr = NULL,
Robert Swiecki82c707c2017-11-14 16:36:23 +0100247 .fileCnt = 0,
248 .fileCntDone = false,
249 .fileExtn = "fuzz",
Robert Swieckiced3eba2017-12-15 15:33:03 +0100250 .workDir = NULL,
251 .crashDir = NULL,
252 .covDirAll = NULL,
253 .covDirNew = NULL,
Robert Swiecki26fd6d52017-11-15 00:46:21 +0100254 .saveUnique = true,
Robert Swiecki363510f2018-03-09 02:00:30 +0100255 .dynfileqCnt = 0U,
256 .dynfileq_mutex = PTHREAD_RWLOCK_INITIALIZER,
Robert Swiecki82c707c2017-11-14 16:36:23 +0100257 },
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100258 .exe =
259 {
Robert Swiecki2aeff252018-01-10 14:58:44 +0100260 .argc = 0,
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100261 .cmdline = NULL,
262 .nullifyStdio = true,
263 .fuzzStdin = false,
264 .externalCommand = NULL,
265 .postExternalCommand = NULL,
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100266 .persistent = false,
267 .netDriver = false,
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100268 .asLimit = 0U,
269 .rssLimit = 0U,
270 .dataLimit = 0U,
271 .clearEnv = false,
272 .envs[0] = NULL,
273 },
Robert Swiecki371e1292017-12-18 01:10:33 +0100274 .timing =
275 {
276 .timeStart = time(NULL),
277 .runEndTime = 0,
278 .tmOut = 10,
Robert Swieckieba27172017-12-18 01:12:02 +0100279 .tmoutVTALRM = false,
Robert Swiecki36f7e512018-01-16 03:46:41 +0100280 .lastCovUpdate = time(NULL),
Robert Swiecki371e1292017-12-18 01:10:33 +0100281 },
Robert Swiecki04dcac32018-03-02 03:05:26 +0100282 .mutate =
283 {
284 .mutationsMax = 0,
285 .dictionaryFile = NULL,
286 .dictionaryCnt = 0,
287 .mutationsPerRun = 6U,
Robert Swieckie9231d62018-03-02 03:35:11 +0100288 .maxFileSz = 0UL,
Robert Swiecki04dcac32018-03-02 03:05:26 +0100289 },
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100290 .display =
291 {
292 .useScreen = true,
Robert Swieckieb9fbdd2018-03-08 05:15:37 +0100293 .lastDisplayMillis = util_timeNowMillis(),
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100294 .cmdline_txt[0] = '\0',
295 },
Robert Swieckia5b918a2018-03-07 23:59:53 +0100296 .cfg =
297 {
298 .useVerifier = false,
299 .exitUponCrash = false,
300 .report_mutex = PTHREAD_MUTEX_INITIALIZER,
301 .reportFile = NULL,
302 .dynFileIterExpire = 0,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200303#if defined(__ANDROID__)
Robert Swieckia5b918a2018-03-07 23:59:53 +0100304 .monitorSIGABRT = false,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200305#else
Robert Swieckia5b918a2018-03-07 23:59:53 +0100306 .monitorSIGABRT = true,
Anestis Bechtsoudise5f09f82016-12-27 16:06:05 +0200307#endif
plusun99ef77e2018-07-31 10:52:27 +0000308 .only_printable = false,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100309 },
310 .sanitizer =
311 {
312 .enable = false,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100313 .extSanOpts = NULL,
314 .covMetadata = NULL,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100315 },
Robert Swieckia5b918a2018-03-07 23:59:53 +0100316 .feedback =
317 {
318 .feedbackMap = NULL,
319 .feedback_mutex = PTHREAD_MUTEX_INITIALIZER,
320 .bbFd = -1,
321 .blacklistFile = NULL,
322 .blacklist = NULL,
323 .blacklistCnt = 0,
324 .skipFeedbackOnTimeout = false,
325 .dynFileMethod = _HF_DYNFILE_SOFT,
Robert Swiecki363510f2018-03-09 02:00:30 +0100326 .state = _HF_STATE_UNSET,
Robert Swieckia5b918a2018-03-07 23:59:53 +0100327 },
Robert Swiecki01a980e2017-11-14 03:36:50 +0100328 .cnts =
329 {
330 .mutationsCnt = 0,
331 .crashesCnt = 0,
332 .uniqueCrashesCnt = 0,
333 .verifiedCrashesCnt = 0,
334 .blCrashesCnt = 0,
335 .timeoutedCnt = 0,
336 },
Robert Swieckia3536a02018-03-08 04:57:51 +0100337 .socketFuzzer =
338 {
339 .enabled = false,
340 .serverSocket = -1,
341 .clientSocket = -1,
342 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200343
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100344 /* Linux code */
Robert Swieckid50ed422017-11-13 23:32:26 +0100345 .linux =
346 {
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200347 .exeFd = -1,
Robert Swieckid50ed422017-11-13 23:32:26 +0100348 .hwCnts =
349 {
350 .cpuInstrCnt = 0ULL,
351 .cpuBranchCnt = 0ULL,
352 .bbCnt = 0ULL,
353 .newBBCnt = 0ULL,
354 .softCntPc = 0ULL,
355 .softCntCmp = 0ULL,
356 },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200357 .dynamicCutOffAddr = ~(0ULL),
358 .disableRandomization = true,
359 .ignoreAddr = NULL,
360 .numMajorFrames = 7,
361 .pid = 0,
362 .pidFile = NULL,
Robert Swiecki06008f72017-12-27 18:40:34 +0100363 .pidCmd = {},
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200364 .symsBlFile = NULL,
365 .symsBlCnt = 0,
366 .symsBl = NULL,
367 .symsWlFile = NULL,
368 .symsWlCnt = 0,
369 .symsWl = NULL,
370 .cloneFlags = 0,
371 .kernelOnly = false,
372 .useClone = true,
Jaggerab26e702016-03-22 04:28:00 +0100373 },
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200374 /* NetBSD code */
375 .netbsd =
376 {
377 .ignoreAddr = NULL,
378 .numMajorFrames = 7,
379 .pid = 0,
380 .pidFile = NULL,
381 .pidCmd = {},
382 .symsBlFile = NULL,
383 .symsBlCnt = 0,
384 .symsBl = NULL,
385 .symsWlFile = NULL,
386 .symsWlCnt = 0,
387 .symsWl = NULL,
388 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200389 };
Robert Swieckia88f96f2015-10-09 16:47:39 +0200390
Robert Swiecki363510f2018-03-09 02:00:30 +0100391 TAILQ_INIT(&hfuzz->io.dynfileq);
Robert Swiecki04dcac32018-03-02 03:05:26 +0100392 TAILQ_INIT(&hfuzz->mutate.dictq);
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100393
Robert Swiecki0b566112017-10-17 17:39:07 +0200394 // clang-format off
Robert Swieckia88f96f2015-10-09 16:47:39 +0200395 struct custom_option custom_opts[] = {
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200396 { { "help", no_argument, NULL, 'h' }, "Help plz.." },
397 { { "input", required_argument, NULL, 'f' }, "Path to a directory containing initial file corpus" },
Robert Swieckie46d8af2018-01-12 03:20:04 +0100398 { { "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 +0200399 { { "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 +0100400 { { "noinst", no_argument, NULL, 'x' }, "Static mode only, disable any instrumentation (hw/sw) feedback" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200401 { { "keep_output", no_argument, NULL, 'Q' }, "Don't close children's stdin, stdout, stderr; can be noisy" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100402 { { "timeout", required_argument, NULL, 't' }, "Timeout in seconds (default: 10)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200403 { { "threads", required_argument, NULL, 'n' }, "Number of concurrent fuzzing threads (default: number of CPUs / 2)" },
404 { { "stdin_input", no_argument, NULL, 's' }, "Provide fuzzing input on STDIN, instead of ___FILE___" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100405 { { "mutations_per_run", required_argument, NULL, 'r' }, "Maximal number of mutations per one run (default: 6)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200406 { { "logfile", required_argument, NULL, 'l' }, "Log file" },
407 { { "verbose", no_argument, NULL, 'v' }, "Disable ANSI console; use simple log output" },
408 { { "verifier", no_argument, NULL, 'V' }, "Enable crashes verifier" },
Robert Swiecki97cd6242017-12-27 21:02:47 +0100409 { { "debug", no_argument, NULL, 'd' }, "Show debug messages (level >= 4)" },
410 { { "quiet", no_argument, NULL, 'q' }, "Show only warnings and more serious messages (level <= 1)" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200411 { { "extension", required_argument, NULL, 'e' }, "Input file extension (e.g. 'swf'), (default: 'fuzz')" },
412 { { "workspace", required_argument, NULL, 'W' }, "Workspace directory to save crashes & runtime files (default: '.')" },
Robert Swieckia35d9d82017-12-15 22:00:41 +0100413 { { "crashdir", required_argument, NULL, 0x600 }, "Directory where crashes are saved to (default: workspace directory)" },
414 { { "covdir_all", required_argument, NULL, 0x601 }, "Coverage is written to a separate directory (default: input directory)" },
415 { { "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 +0200416 { { "dict", required_argument, NULL, 'w' }, "Dictionary file. Format:http://llvm.org/docs/LibFuzzer.html#dictionaries" },
417 { { "stackhash_bl", required_argument, NULL, 'B' }, "Stackhashes blacklist file (one entry per line)" },
418 { { "mutate_cmd", required_argument, NULL, 'c' }, "External command producing fuzz files (instead of internal mutators)" },
419 { { "pprocess_cmd", required_argument, NULL, 0x104 }, "External command postprocessing files produced by internal mutators" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100420 { { "run_time", required_argument, NULL, 0x109 }, "Number of seconds this fuzzing session will last (default: 0 [no limit])" },
421 { { "iterations", required_argument, NULL, 'N' }, "Number of fuzzing iterations (default: 0 [no limit])" },
422 { { "rlimit_as", required_argument, NULL, 0x100 }, "Per process RLIMIT_AS in MiB (default: 0 [no limit])" },
423 { { "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" },
424 { { "rlimit_data", required_argument, NULL, 0x102 }, "Per process RLIMIT_DATA in MiB (default: 0 [no limit])" },
Robert Swieckic58ca512018-11-06 17:50:37 +0100425 { { "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 +0100426 { { "report", required_argument, NULL, 'R' }, "Write report to this file (default: '<workdir>/" _HF_REPORT_FILE "')" },
427 { { "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 +0100428 { { "clear_env", no_argument, NULL, 0x108 }, "Clear all environment variables before executing the binary" },
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200429 { { "env", required_argument, NULL, 'E' }, "Pass this environment variable, can be used multiple times" },
430 { { "save_all", no_argument, NULL, 'u' }, "Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames" },
431 { { "tmout_sigvtalrm", no_argument, NULL, 'T' }, "Use SIGVTALRM to kill timeouting processes (default: use SIGKILL)" },
432 { { "sanitizers", no_argument, NULL, 'S' }, "Enable sanitizers settings (default: false)" },
Robert Swiecki97d88932018-01-10 19:29:34 +0100433 { { "san_opts", required_argument, NULL, 0x10A }, "Options appended to the regular *SAN_OPTIONS (default: empty)" },
Robert Swieckib1f5a252018-01-22 16:05:39 +0100434 { { "monitor_sigabrt", required_argument, NULL, 0x105 }, "Monitor SIGABRT (default: false for Android, true for other platforms)" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100435 { { "no_fb_timeout", required_argument, NULL, 0x106 }, "Skip feedback if the process has timeouted (default: false)" },
436 { { "exit_upon_crash", no_argument, NULL, 0x107 }, "Exit upon seeing the first crash (default: false)" },
dobinedf9f8d2018-01-21 13:57:02 +0100437 { { "socket_fuzzer", no_argument, NULL, 0x10b }, "Instrument external fuzzer via socket" },
plusun99ef77e2018-07-31 10:52:27 +0000438 { { "only_printable", no_argument, NULL, 'o' }, "Only generate printable inputs" },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200439
440#if defined(_HF_ARCH_LINUX)
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200441 { { "linux_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
442 { { "linux_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
443 { { "linux_pid", required_argument, NULL, 'p' }, "Attach to a pid (and its thread group)" },
444 { { "linux_file_pid", required_argument, NULL, 0x502 }, "Attach to pid (and its thread group) read from file" },
Robert Swieckiac640e02018-01-22 16:04:45 +0100445 { { "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 +0200446 { { "linux_keep_aslr", no_argument, NULL, 0x501 }, "Don't disable ASLR randomization, might be useful with MSAN" },
447 { { "linux_perf_ignore_above", required_argument, NULL, 0x503 }, "Ignore perf events which report IPs above this address" },
448 { { "linux_perf_instr", no_argument, NULL, 0x510 }, "Use PERF_COUNT_HW_INSTRUCTIONS perf" },
449 { { "linux_perf_branch", no_argument, NULL, 0x511 }, "Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf" },
450 { { "linux_perf_bts_edge", no_argument, NULL, 0x513 }, "Use Intel BTS to count unique edges" },
451 { { "linux_perf_ipt_block", no_argument, NULL, 0x514 }, "Use Intel Processor Trace to count unique blocks (requires libipt.so)" },
452 { { "linux_perf_kernel_only", no_argument, NULL, 0x515 }, "Gather kernel-only coverage with Intel PT and with Intel BTS" },
453 { { "linux_ns_net", no_argument, NULL, 0x0530 }, "Use Linux NET namespace isolation" },
454 { { "linux_ns_pid", no_argument, NULL, 0x0531 }, "Use Linux PID namespace isolation" },
455 { { "linux_ns_ipc", no_argument, NULL, 0x0532 }, "Use Linux IPC namespace isolation" },
456#endif // defined(_HF_ARCH_LINUX)
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200457
458#if defined(_HF_ARCH_NETBSD)
459 { { "netbsd_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
460 { { "netbsd_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
461 { { "netbsd_pid", required_argument, NULL, 'p' }, "Attach to a pid (and its thread group)" },
462 { { "netbsd_file_pid", required_argument, NULL, 0x502 }, "Attach to pid (and its thread group) read from file" },
463 { { "netbsd_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: 0)" },
464#endif // defined(_HF_ARCH_NETBSD)
Robert Swieckid0fa62c2017-09-28 18:11:05 +0200465 { { 0, 0, 0, 0 }, NULL },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200466 };
Robert Swiecki0b566112017-10-17 17:39:07 +0200467 // clang-format on
Robert Swieckia88f96f2015-10-09 16:47:39 +0200468
469 struct option opts[ARRAYSIZE(custom_opts)];
470 for (unsigned i = 0; i < ARRAYSIZE(custom_opts); i++) {
471 opts[i] = custom_opts[i].opt;
472 }
473
474 enum llevel_t ll = INFO;
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200475 const char* logfile = NULL;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200476 int opt_index = 0;
477 for (;;) {
Robert Swiecki0b566112017-10-17 17:39:07 +0200478 int c = getopt_long(
Robert Swiecki8267c772018-08-23 23:21:40 +0200479 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 +0100480 if (c < 0) break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200481
482 switch (c) {
Robert Swieckid50ed422017-11-13 23:32:26 +0100483 case 'h':
484 case '?':
485 cmdlineUsage(argv[0], custom_opts);
486 break;
487 case 'f':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100488 hfuzz->io.inputDir = optarg;
Robert Swieckiced3eba2017-12-15 15:33:03 +0100489 if (hfuzz->io.covDirAll == NULL) {
490 hfuzz->io.covDirAll = optarg;
491 }
Robert Swieckid50ed422017-11-13 23:32:26 +0100492 break;
493 case 'x':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100494 hfuzz->feedback.dynFileMethod = _HF_DYNFILE_NONE;
Robert Swieckid50ed422017-11-13 23:32:26 +0100495 break;
496 case 'Q':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100497 hfuzz->exe.nullifyStdio = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100498 break;
499 case 'v':
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100500 hfuzz->display.useScreen = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100501 break;
502 case 'V':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100503 hfuzz->cfg.useVerifier = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100504 break;
505 case 's':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100506 hfuzz->exe.fuzzStdin = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100507 break;
508 case 'u':
Robert Swiecki26fd6d52017-11-15 00:46:21 +0100509 hfuzz->io.saveUnique = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100510 break;
511 case 'l':
512 logfile = optarg;
513 break;
514 case 'd':
Robert Swiecki97cd6242017-12-27 21:02:47 +0100515 ll = DEBUG;
516 break;
517 case 'q':
518 ll = WARNING;
Robert Swieckid50ed422017-11-13 23:32:26 +0100519 break;
520 case 'e':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100521 hfuzz->io.fileExtn = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100522 break;
523 case 'W':
Robert Swiecki82c707c2017-11-14 16:36:23 +0100524 hfuzz->io.workDir = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100525 break;
Robert Swieckia35d9d82017-12-15 22:00:41 +0100526 case 0x600:
Robert Swieckiced3eba2017-12-15 15:33:03 +0100527 hfuzz->io.crashDir = optarg;
528 break;
Robert Swieckia35d9d82017-12-15 22:00:41 +0100529 case 0x601:
530 hfuzz->io.covDirAll = optarg;
531 break;
532 case 0x602:
533 hfuzz->io.covDirNew = optarg;
534 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100535 case 'r':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100536 hfuzz->mutate.mutationsPerRun = strtoul(optarg, NULL, 10);
Robert Swieckid50ed422017-11-13 23:32:26 +0100537 break;
538 case 'c':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100539 hfuzz->exe.externalCommand = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100540 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100541 case 'S':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100542 hfuzz->sanitizer.enable = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100543 break;
Robert Swiecki97d88932018-01-10 19:29:34 +0100544 case 0x10A:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100545 hfuzz->sanitizer.extSanOpts = optarg;
Robert Swiecki97d88932018-01-10 19:29:34 +0100546 break;
dobinedf9f8d2018-01-21 13:57:02 +0100547 case 0x10B:
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100548 hfuzz->socketFuzzer.enabled = true;
Robert Swiecki56276192018-01-21 15:43:02 +0100549 hfuzz->timing.tmOut = 0; // Disable process timeout checks
dobinedf9f8d2018-01-21 13:57:02 +0100550 break;
plusun99ef77e2018-07-31 10:52:27 +0000551 case 'o':
552 hfuzz->cfg.only_printable = true;
553 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100554 case 'z':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100555 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_SOFT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100556 break;
557 case 'F':
Robert Swieckie9231d62018-03-02 03:35:11 +0100558 hfuzz->mutate.maxFileSz = strtoul(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100559 break;
560 case 't':
Robert Swiecki371e1292017-12-18 01:10:33 +0100561 hfuzz->timing.tmOut = atol(optarg);
Robert Swieckid50ed422017-11-13 23:32:26 +0100562 break;
563 case 'R':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100564 hfuzz->cfg.reportFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100565 break;
566 case 'n':
567 hfuzz->threads.threadsMax = atol(optarg);
568 break;
569 case 0x109: {
570 time_t p = atol(optarg);
571 if (p > 0) {
Robert Swiecki371e1292017-12-18 01:10:33 +0100572 hfuzz->timing.runEndTime = time(NULL) + p;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200573 }
Robert Swieckid50ed422017-11-13 23:32:26 +0100574 } break;
575 case 'N':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100576 hfuzz->mutate.mutationsMax = atol(optarg);
Robert Swieckid50ed422017-11-13 23:32:26 +0100577 break;
578 case 0x100:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100579 hfuzz->exe.asLimit = strtoull(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100580 break;
581 case 0x101:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100582 hfuzz->exe.rssLimit = strtoull(optarg, NULL, 0);
Robert Swiecki8954afd2017-11-14 18:14:22 +0100583 break;
584 case 0x102:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100585 hfuzz->exe.dataLimit = strtoull(optarg, NULL, 0);
Robert Swieckid50ed422017-11-13 23:32:26 +0100586 break;
Robert Swieckic58ca512018-11-06 17:50:37 +0100587 case 0x103:
588 hfuzz->exe.coreLimit = strtoull(optarg, NULL, 0);
589 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100590 case 0x104:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100591 hfuzz->exe.postExternalCommand = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100592 break;
593 case 0x105:
594 if ((strcasecmp(optarg, "0") == 0) || (strcasecmp(optarg, "false") == 0)) {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100595 hfuzz->cfg.monitorSIGABRT = false;
Robert Swieckid50ed422017-11-13 23:32:26 +0100596 } else {
Robert Swieckia5b918a2018-03-07 23:59:53 +0100597 hfuzz->cfg.monitorSIGABRT = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100598 }
599 break;
600 case 0x106:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100601 hfuzz->feedback.skipFeedbackOnTimeout = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100602 break;
603 case 0x107:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100604 hfuzz->cfg.exitUponCrash = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100605 break;
Robert Swiecki8954afd2017-11-14 18:14:22 +0100606 case 0x108:
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100607 hfuzz->exe.clearEnv = true;
Robert Swiecki8954afd2017-11-14 18:14:22 +0100608 break;
Robert Swieckid50ed422017-11-13 23:32:26 +0100609 case 'P':
Robert Swiecki5cc1f7b2018-01-16 20:55:43 +0100610 hfuzz->exe.persistent = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100611 break;
612 case 'T':
Robert Swieckieba27172017-12-18 01:12:02 +0100613 hfuzz->timing.tmoutVTALRM = true;
Robert Swieckid50ed422017-11-13 23:32:26 +0100614 break;
615 case 'p':
616 if (util_isANumber(optarg) == false) {
617 LOG_E("-p '%s' is not a number", optarg);
618 return false;
619 }
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200620#if defined(_HF_ARCH_LINUX)
Robert Swieckid50ed422017-11-13 23:32:26 +0100621 hfuzz->linux.pid = atoi(optarg);
622 if (hfuzz->linux.pid < 1) {
623 LOG_E("-p '%d' is invalid", hfuzz->linux.pid);
624 return false;
625 }
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200626#elif defined(_HF_ARCH_NETBSD)
627 hfuzz->netbsd.pid = atoi(optarg);
628 if (hfuzz->netbsd.pid < 1) {
629 LOG_E("-p '%d' is invalid", hfuzz->netbsd.pid);
630 return false;
631 }
632#endif
Robert Swieckid50ed422017-11-13 23:32:26 +0100633 break;
634 case 0x502:
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200635#if defined(_HF_ARCH_LINUX)
Robert Swieckid50ed422017-11-13 23:32:26 +0100636 hfuzz->linux.pidFile = optarg;
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200637#elif defined(_HF_ARCH_NETBSD)
638 hfuzz->netbsd.pidFile = optarg;
639#endif
Robert Swieckid50ed422017-11-13 23:32:26 +0100640 break;
641 case 'E':
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100642 for (size_t i = 0; i < ARRAYSIZE(hfuzz->exe.envs); i++) {
643 if (hfuzz->exe.envs[i] == NULL) {
644 hfuzz->exe.envs[i] = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100645 break;
646 }
647 }
648 break;
649 case 'w':
Robert Swiecki04dcac32018-03-02 03:05:26 +0100650 hfuzz->mutate.dictionaryFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100651 break;
652 case 'B':
Robert Swieckia5b918a2018-03-07 23:59:53 +0100653 hfuzz->feedback.blacklistFile = optarg;
Robert Swieckid50ed422017-11-13 23:32:26 +0100654 break;
Robert Swiecki846ccd72017-01-12 17:52:23 +0100655#if defined(_HF_ARCH_LINUX)
Robert Swieckid50ed422017-11-13 23:32:26 +0100656 case 0x500:
657 hfuzz->linux.ignoreAddr = (void*)strtoul(optarg, NULL, 0);
658 break;
659 case 0x501:
660 hfuzz->linux.disableRandomization = false;
661 break;
662 case 0x503:
663 hfuzz->linux.dynamicCutOffAddr = strtoull(optarg, NULL, 0);
664 break;
665 case 0x504:
666 hfuzz->linux.symsBlFile = optarg;
667 break;
668 case 0x505:
669 hfuzz->linux.symsWlFile = optarg;
670 break;
671 case 0x510:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100672 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100673 break;
674 case 0x511:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100675 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
Robert Swieckid50ed422017-11-13 23:32:26 +0100676 break;
677 case 0x513:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100678 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
Robert Swieckid50ed422017-11-13 23:32:26 +0100679 break;
680 case 0x514:
Robert Swieckia5b918a2018-03-07 23:59:53 +0100681 hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
Robert Swieckid50ed422017-11-13 23:32:26 +0100682 break;
683 case 0x515:
684 hfuzz->linux.kernelOnly = true;
685 break;
686 case 0x530:
687 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWNET);
688 break;
689 case 0x531:
690 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWPID);
691 break;
692 case 0x532:
693 hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWIPC);
694 break;
Robert Swiecki4e595fb2017-10-11 17:26:51 +0200695#endif /* defined(_HF_ARCH_LINUX) */
Kamil Rytarowski45a1cf42018-08-15 06:26:26 +0200696#if defined(_HF_ARCH_NETBSD)
697 case 0x500:
698 hfuzz->netbsd.ignoreAddr = (void*)strtoul(optarg, NULL, 0);
699 break;
700 case 0x504:
701 hfuzz->netbsd.symsBlFile = optarg;
702 break;
703 case 0x505:
704 hfuzz->netbsd.symsWlFile = optarg;
705 break;
706#endif /* defined(_HF_ARCH_NETBSD) */
Robert Swieckid50ed422017-11-13 23:32:26 +0100707 default:
708 cmdlineUsage(argv[0], custom_opts);
709 return false;
710 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200711 }
712 }
Jagger72f258b2015-10-09 23:09:01 +0200713
Robert Swieckia35d9d82017-12-15 22:00:41 +0100714 if (!logInitLogFile(logfile, ll)) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200715 return false;
716 }
Robert Swiecki2aeff252018-01-10 14:58:44 +0100717 hfuzz->exe.argc = argc - optind;
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100718 hfuzz->exe.cmdline = (const char* const*)&argv[optind];
Robert Swiecki2aeff252018-01-10 14:58:44 +0100719 if (hfuzz->exe.argc <= 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200720 LOG_E("No fuzz command provided");
721 cmdlineUsage(argv[0], custom_opts);
722 return false;
723 }
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100724 if (!files_exists(hfuzz->exe.cmdline[0])) {
725 LOG_E("Your fuzzed binary '%s' doesn't seem to exist", hfuzz->exe.cmdline[0]);
726 return false;
727 }
Robert Swieckia35d9d82017-12-15 22:00:41 +0100728 if (!cmdlineVerify(hfuzz)) {
Anestis Bechtsoudisc1a0d9f2016-12-29 11:34:10 +0200729 return false;
730 }
731
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100732 display_createTargetStr(hfuzz);
733
Robert Swieckid50ed422017-11-13 23:32:26 +0100734 LOG_I(
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100735 "cmdline: '%s' pid: %d, inputDir '%s', nullifyStdio: %s, fuzzStdin: %s, saveUnique: %s, "
Robert Swieckid50ed422017-11-13 23:32:26 +0100736 "mutationsPerRun: %u, "
737 "externalCommand: '%s', runEndTime: %d tmOut: %ld, mutationsMax: %zu, "
738 "threads.threadsMax: %zu, "
739 "fileExtn: '%s', "
Robert Swiecki8954afd2017-11-14 18:14:22 +0100740 "ASLimit: 0x%" PRIx64 "(MiB), RSSLimit: 0x%" PRIx64 ", DATALimit: 0x%" PRIx64
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200741 ", fuzzExe: '%s', "
742#if defined(_HF_ARCH_LINUX) || defined(_HF_ARCH_NETBSD)
743 "fuzzedPid: %d, "
744#endif
745 "monitorSIGABRT: '%s'",
Robert Swiecki5e26bd92018-03-02 12:09:34 +0100746 hfuzz->display.cmdline_txt, (int)getpid(), hfuzz->io.inputDir,
Robert Swiecki8a1fc672018-01-25 23:22:47 +0100747 cmdlineYesNo(hfuzz->exe.nullifyStdio), cmdlineYesNo(hfuzz->exe.fuzzStdin),
Robert Swiecki04dcac32018-03-02 03:05:26 +0100748 cmdlineYesNo(hfuzz->io.saveUnique), hfuzz->mutate.mutationsPerRun,
Robert Swiecki97d0cee2017-12-18 00:17:50 +0100749 hfuzz->exe.externalCommand == NULL ? "NULL" : hfuzz->exe.externalCommand,
Robert Swiecki04dcac32018-03-02 03:05:26 +0100750 (int)hfuzz->timing.runEndTime, (long)hfuzz->timing.tmOut, hfuzz->mutate.mutationsMax,
Robert Swiecki371e1292017-12-18 01:10:33 +0100751 hfuzz->threads.threadsMax, hfuzz->io.fileExtn, hfuzz->exe.asLimit, hfuzz->exe.rssLimit,
Kamil Rytarowskibdfe2a72018-08-18 12:28:29 +0200752 hfuzz->exe.dataLimit, hfuzz->exe.cmdline[0],
753#if defined(_HF_ARCH_LINUX)
754 hfuzz->linux.pid,
755#elif defined(_HF_ARCH_NETBSD)
756 hfuzz->netbsd.pid,
757#endif
Robert Swieckia5b918a2018-03-07 23:59:53 +0100758 cmdlineYesNo(hfuzz->cfg.monitorSIGABRT));
Robert Swieckia88f96f2015-10-09 16:47:39 +0200759
Robert Swieckia88f96f2015-10-09 16:47:39 +0200760 return true;
761}