blob: 9c27223f5d9b5da0de6a18bde404436f70910bd4 [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 Swieckia88f96f2015-10-09 16:47:39 +020030#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010033#include <sys/queue.h>
Robert Swieckia88f96f2015-10-09 16:47:39 +020034#include <unistd.h>
35
36#include "common.h"
37#include "log.h"
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +020038#include "files.h"
Robert Swiecki72d2bef2016-01-19 14:39:26 +010039#include "util.h"
Robert Swieckia88f96f2015-10-09 16:47:39 +020040
41struct custom_option {
42 struct option opt;
43 const char *descr;
44};
45
46static bool checkFor_FILE_PLACEHOLDER(char **args)
47{
48 for (int x = 0; args[x]; x++) {
49 if (strstr(args[x], _HF_FILE_PLACEHOLDER))
50 return true;
51 }
52 return false;
53}
54
55static const char *cmdlineYesNo(bool yes)
56{
57 return (yes ? "true" : "false");
58}
59
60static void cmdlineHelp(const char *pname, struct custom_option *opts)
61{
62 LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
63 LOG_HELP_BOLD("Options:");
64 for (int i = 0; opts[i].opt.name; i++) {
65 if (isprint(opts[i].opt.val)) {
66 LOG_HELP_BOLD(" --%s%s%c %s", opts[i].opt.name,
67 "|-", opts[i].opt.val,
Robert Swieckibf063db2016-02-16 18:42:00 +010068 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +020069 } else {
70 LOG_HELP_BOLD(" --%s %s", opts[i].opt.name,
Robert Swieckibf063db2016-02-16 18:42:00 +010071 opts[i].opt.has_arg == required_argument ? "VALUE" : "");
Robert Swieckia88f96f2015-10-09 16:47:39 +020072 }
73 LOG_HELP("\t%s", opts[i].descr);
74 }
Jagger32127372015-10-09 23:07:38 +020075 LOG_HELP_BOLD("\nExamples:");
76 LOG_HELP(" Run the binary over a mutated file chosen from the directory");
77 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
78 LOG_HELP(" As above, provide input over STDIN:");
Robert Swiecki72d2bef2016-01-19 14:39:26 +010079 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -s -- /usr/bin/djpeg");
Robert Swieckia88f96f2015-10-09 16:47:39 +020080#if defined(_HF_ARCH_LINUX)
Jagger32127372015-10-09 23:07:38 +020081 LOG_HELP(" Run the binary over a dynamic file, maximize total no. of instructions:");
Jagger72f258b2015-10-09 23:09:01 +020082 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_instr -- /usr/bin/tiffinfo -D "
83 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020084 LOG_HELP(" Run the binary over a dynamic file, maximize total no. of branches:");
Jagger72f258b2015-10-09 23:09:01 +020085 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_branch -- /usr/bin/tiffinfo -D "
86 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020087 LOG_HELP(" Run the binary over a dynamic file, maximize unique code blocks (coverage):");
88 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
89 LOG_HELP(" Run the binary over a dynamic file, maximize unique branches (edges):");
Jagger72f258b2015-10-09 23:09:01 +020090 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip_addr -- /usr/bin/tiffinfo -D "
91 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020092 LOG_HELP(" Run the binary over a dynamic file, maximize custom counters (experimental):");
Jagger72f258b2015-10-09 23:09:01 +020093 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_custom -- /usr/bin/tiffinfo -D "
94 _HF_FILE_PLACEHOLDER);
Robert Swieckia88f96f2015-10-09 16:47:39 +020095#endif /* defined(_HF_ARCH_LINUX) */
Robert Swieckia88f96f2015-10-09 16:47:39 +020096}
97
98static void cmdlineUsage(const char *pname, struct custom_option *opts)
99{
100 cmdlineHelp(pname, opts);
101 exit(0);
102}
103
Robert Swieckia88f96f2015-10-09 16:47:39 +0200104rlim_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul)
105{
106 struct rlimit cur;
107 if (getrlimit(res, &cur) == -1) {
108 PLOG_F("getrlimit(%d)", res);
109 }
110 if (strcasecmp(optarg, "max") == 0) {
111 return cur.rlim_max;
112 }
113 if (strcasecmp(optarg, "def") == 0) {
114 return cur.rlim_cur;
115 }
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200116 if (util_isANumber(optarg) == false) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200117 LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
118 }
119 rlim_t val = strtoul(optarg, NULL, 0) * mul;
Jagger2bd61b72015-10-10 05:23:32 +0200120 if ((unsigned long)val == ULONG_MAX && errno != 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200121 PLOG_F("strtoul('%s', 0)", optarg);
122 }
123 return val;
124}
125
126bool cmdlineParse(int argc, char *argv[], honggfuzz_t * hfuzz)
127{
128 /* *INDENT-OFF* */
129 (*hfuzz) = (honggfuzz_t) {
130 .cmdline = NULL,
Robert Swiecki72d2bef2016-01-19 14:39:26 +0100131 .cmdline_txt[0] = '\0',
Robert Swieckia88f96f2015-10-09 16:47:39 +0200132 .inputFile = NULL,
133 .nullifyStdio = false,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200134 .fuzzStdin = false,
135 .saveUnique = true,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100136 .useScreen = true,
137 .useVerifier = false,
138 .timeStart = time(NULL),
Robert Swieckia88f96f2015-10-09 16:47:39 +0200139 .fileExtn = "fuzz",
140 .workDir = ".",
Robert Swieckia96d78d2016-03-14 16:50:50 +0100141 .origFlipRate = 0.001f,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200142 .externalCommand = NULL,
143 .dictionaryFile = NULL,
144 .dictionary = NULL,
145 .dictionaryCnt = 0,
146 .blacklistFile = NULL,
147 .blacklistCnt = 0,
148 .blacklist = NULL,
149 .maxFileSz = (1024 * 1024),
150 .tmOut = 3,
151 .mutationsMax = 0,
152 .threadsFinished = 0,
153 .threadsMax = 2,
154 .reportFile = NULL,
155 .asLimit = 0ULL,
156 .files = NULL,
157 .fileCnt = 0,
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200158 .lastCheckedFileIndex = 0,
Jaggercdbf6852016-02-07 22:06:02 +0100159 .exeFd = -1,
Jagger80041fe2016-03-10 21:32:35 +0100160 .clearEnv = false,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200161 .envs = {[0 ... (ARRAYSIZE(hfuzz->envs) - 1)] = NULL,},
162
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100163 .state = _HF_STATE_UNSET,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100164 .bbMapSz = _HF_PERF_BITMAP_SIZE,
165 .bbMap = util_Malloc(_HF_PERF_BITMAP_SIZE),
166 .dynfileqCnt = 0U,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100167
Robert Swieckia88f96f2015-10-09 16:47:39 +0200168 .mutationsCnt = 0,
169 .crashesCnt = 0,
170 .uniqueCrashesCnt = 0,
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200171 .verifiedCrashesCnt = 0,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200172 .blCrashesCnt = 0,
173 .timeoutedCnt = 0,
174
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100175 .dynFileMethod = _HF_DYNFILE_NONE,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200176 .sanCovCnts = {
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200177 .hitBBCnt = 0ULL,
178 .totalBBCnt = 0ULL,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200179 .dsoCnt = 0ULL,
180 .iDsoCnt = 0ULL,
Anestis Bechtsoudis56e360f2016-01-11 14:29:17 +0200181 .newBBCnt = 0ULL,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200182 .crashesCnt = 0ULL,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200183 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200184 .dynamicFile_mutex = PTHREAD_MUTEX_INITIALIZER,
185
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200186 .sanCov_mutex = PTHREAD_MUTEX_INITIALIZER,
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100187 .sanOpts = {
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200188 .asanOpts = NULL,
189 .msanOpts = NULL,
190 .ubsanOpts = NULL,
191 },
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100192 .useSanCov = false,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100193 .covMetadata = NULL,
194
195 /* Linux code */
196 .hwCnts = {
197 .cpuInstrCnt = 0ULL,
198 .cpuBranchCnt = 0ULL,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100199 .customCnt = 0ULL,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100200 .bbCnt = 0ULL,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100201 },
202 .dynamicCutOffAddr = ~(0ULL),
203 .disableRandomization = true,
204 .msanReportUMRS = false,
205 .ignoreAddr = NULL,
206 .numMajorFrames = 7,
207 .pid = 0,
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200208 .pidFile = NULL,
Anestis Bechtsoudis7c88d7a2016-02-09 17:55:38 +0200209 .pidCmd = NULL,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200210 };
211 /* *INDENT-ON* */
212
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100213 TAILQ_INIT(&hfuzz->dynfileq);
214
Robert Swieckia88f96f2015-10-09 16:47:39 +0200215 /* *INDENT-OFF* */
216 struct custom_option custom_opts[] = {
217 {{"help", no_argument, NULL, 'h'}, "Help plz.."},
218 {{"input", required_argument, NULL, 'f'}, "Path to the file corpus (file or a directory)"},
219 {{"nullify_stdio", no_argument, NULL, 'q'}, "Null-ify children's stdin, stdout, stderr; make them quiet"},
220 {{"stdin_input", no_argument, NULL, 's'}, "Provide fuzzing input on STDIN, instead of ___FILE___"},
221 {{"save_all", no_argument, NULL, 'u'}, "Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames"},
Robert Swiecki03ef5312015-10-09 18:25:40 +0200222 {{"logfile", required_argument, NULL, 'l'}, "Log file"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200223 {{"verbose", no_argument, NULL, 'v'}, "Disable ANSI console; use simple log output"},
Anestis Bechtsoudis4a3c8e82015-11-07 18:59:14 +0200224#if defined(_HF_ARCH_LINUX) || defined(_HF_ARCH_DARWIN)
Jagger5ff08ac2016-02-09 22:15:58 +0100225 {{"verifier", no_argument, NULL, 'V'}, "Enable crashes verifier"},
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700226#endif
Robert Swieckia88f96f2015-10-09 16:47:39 +0200227 {{"debug_level", required_argument, NULL, 'd'}, "Debug level (0 - FATAL ... 4 - DEBUG), (default: '3' [INFO])"},
228 {{"extension", required_argument, NULL, 'e'}, "Input file extension (e.g. 'swf'), (default: 'fuzz')"},
229 {{"wokspace", required_argument, NULL, 'W'}, "Workspace directory to save crashes & runtime files (default: '.')"},
230 {{"flip_rate", required_argument, NULL, 'r'}, "Maximal flip rate, (default: '0.001')"},
231 {{"wordlist", required_argument, NULL, 'w'}, "Wordlist file (tokens delimited by NUL-bytes)"},
232 {{"stackhash_bl", required_argument, NULL, 'B'}, "Stackhashes blacklist file (one entry per line)"},
233 {{"mutate_cmd", required_argument, NULL, 'c'}, "External command modifying the input corpus of files, instead of -r/-m parameters"},
234 {{"timeout", required_argument, NULL, 't'}, "Timeout in seconds (default: '3')"},
235 {{"threads", required_argument, NULL, 'n'}, "Number of concurrent fuzzing threads (default: '2')"},
236 {{"iterations", required_argument, NULL, 'N'}, "Number of fuzzing iterations (default: '0' [no limit])"},
Robert Swiecki03ef5312015-10-09 18:25:40 +0200237 {{"rlimit_as", required_argument, NULL, 0x100}, "Per process memory limit in MiB (default: '0' [no limit])"},
dyjakanebfd24e2015-10-16 19:24:32 +0100238 {{"report", required_argument, NULL, 'R'}, "Write report to this file (default: '" _HF_REPORT_FILE "')"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200239 {{"max_file_size", required_argument, NULL, 'F'}, "Maximal size of files processed by the fuzzer in bytes (default: '1048576')"},
Jagger80041fe2016-03-10 21:32:35 +0100240 {{"clear_env", no_argument, NULL, 0x101}, "Clear all environment variables before executing the binary"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200241 {{"env", required_argument, NULL, 'E'}, "Pass this environment variable, can be used multiple times"},
Jagger3db1d952016-03-10 02:02:46 +0100242 {{"sancov", no_argument, NULL, 'C'}, "Enable sanitizer coverage feedback"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200243
244#if defined(_HF_ARCH_LINUX)
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200245 {{"linux_pid", required_argument, NULL, 'p'}, "Attach to a pid (and its thread group)"},
246 {{"linux_file_pid", required_argument, NULL, 'P'}, "Attach to pid (and its thread group) read from file"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200247 {{"linux_addr_low_limit", required_argument, NULL, 0x500}, "Address limit (from si.si_addr) below which crashes are not reported, (default: '0')"},
248 {{"linux_keep_aslr", no_argument, NULL, 0x501}, "Don't disable ASLR randomization, might be useful with MSAN"},
249 {{"linux_report_msan_umrs", no_argument, NULL, 0x502}, "Report MSAN's UMRS (uninitialized memory access)"},
Jaggerae6a4452015-10-14 17:34:43 +0200250 {{"linux_perf_ignore_above", required_argument, NULL, 0x503}, "Ignore perf events which report IPs above this address"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200251 {{"linux_perf_instr", no_argument, NULL, 0x510}, "Use PERF_COUNT_HW_INSTRUCTIONS perf"},
252 {{"linux_perf_branch", no_argument, NULL, 0x511}, "Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf"},
Jagger39bd2b02016-02-04 01:16:15 +0100253 {{"linux_perf_bts_block", no_argument, NULL, 0x512}, "Use Intel BTS to count unique blocks"},
254 {{"linux_perf_bts_edge", no_argument, NULL, 0x513}, "Use Intel BTS to count unique edges"},
255 {{"linux_perf_ipt_block", no_argument, NULL, 0x514}, "Use Intel Processor Trace to count unique blocks"},
Jagger39bd2b02016-02-04 01:16:15 +0100256 {{"linux_perf_custom", no_argument, NULL, 0x520}, "Custom counter (see the interceptor/ directory for examples)"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200257#endif // defined(_HF_ARCH_LINUX)
258 {{0, 0, 0, 0}, NULL},
259 };
260 /* *INDENT-ON* */
261
262 struct option opts[ARRAYSIZE(custom_opts)];
263 for (unsigned i = 0; i < ARRAYSIZE(custom_opts); i++) {
264 opts[i] = custom_opts[i].opt;
265 }
266
267 enum llevel_t ll = INFO;
268 const char *logfile = NULL;
269 int opt_index = 0;
270 for (;;) {
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200271 int c = getopt_long(argc, argv, "-?hqvVsuf:d:e:W:r:c:F:t:R:n:N:l:p:P:g:E:w:B:C", opts,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200272 &opt_index);
273 if (c < 0)
274 break;
275
276 switch (c) {
277 case 'h':
278 case '?':
279 cmdlineUsage(argv[0], custom_opts);
280 break;
281 case 'f':
282 hfuzz->inputFile = optarg;
283 break;
284 case 'q':
285 hfuzz->nullifyStdio = true;
286 break;
287 case 'v':
288 hfuzz->useScreen = false;
289 break;
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700290 case 'V':
291 hfuzz->useVerifier = true;
292 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200293 case 's':
294 hfuzz->fuzzStdin = true;
295 break;
296 case 'u':
297 hfuzz->saveUnique = false;
298 break;
Robert Swiecki03ef5312015-10-09 18:25:40 +0200299 case 'l':
300 logfile = optarg;
301 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200302 case 'd':
303 ll = atoi(optarg);
304 break;
305 case 'e':
306 hfuzz->fileExtn = optarg;
307 break;
308 case 'W':
309 hfuzz->workDir = optarg;
310 break;
311 case 'r':
Robert Swieckia96d78d2016-03-14 16:50:50 +0100312 hfuzz->origFlipRate = strtod(optarg, NULL);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200313 break;
314 case 'c':
315 hfuzz->externalCommand = optarg;
316 break;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200317 case 'C':
318 hfuzz->useSanCov = true;
319 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200320 case 'F':
321 hfuzz->maxFileSz = strtoul(optarg, NULL, 0);
322 break;
323 case 't':
324 hfuzz->tmOut = atol(optarg);
325 break;
326 case 'R':
327 hfuzz->reportFile = optarg;
328 break;
329 case 'n':
330 hfuzz->threadsMax = atol(optarg);
331 break;
332 case 'N':
333 hfuzz->mutationsMax = atol(optarg);
334 break;
Robert Swiecki03ef5312015-10-09 18:25:40 +0200335 case 0x100:
Robert Swieckia88f96f2015-10-09 16:47:39 +0200336 hfuzz->asLimit = strtoull(optarg, NULL, 0);
337 break;
Jagger80041fe2016-03-10 21:32:35 +0100338 case 0x101:
339 hfuzz->clearEnv = true;
340 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200341 case 'p':
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200342 if (util_isANumber(optarg) == false) {
Jagger9c4d1622015-10-16 01:40:17 +0200343 LOG_E("-p '%s' is not a number", optarg);
344 return false;
345 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200346 hfuzz->pid = atoi(optarg);
Jagger9c4d1622015-10-16 01:40:17 +0200347 if (hfuzz->pid < 1) {
348 LOG_E("-p '%d' is invalid", hfuzz->pid);
349 return false;
350 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200351 break;
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200352 case 'P':
353 hfuzz->pidFile = optarg;
354 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200355 case 'E':
356 for (size_t i = 0; i < ARRAYSIZE(hfuzz->envs); i++) {
357 if (hfuzz->envs[i] == NULL) {
358 hfuzz->envs[i] = optarg;
359 break;
360 }
361 }
362 break;
363 case 'w':
364 hfuzz->dictionaryFile = optarg;
365 break;
366 case 'B':
367 hfuzz->blacklistFile = optarg;
368 break;
369 case 0x500:
370 hfuzz->ignoreAddr = (void *)strtoul(optarg, NULL, 0);
371 break;
372 case 0x501:
373 hfuzz->disableRandomization = false;
374 break;
375 case 0x502:
376 hfuzz->msanReportUMRS = true;
377 break;
378 case 0x503:
Jagger0b21ebb2015-10-14 17:39:15 +0200379 hfuzz->dynamicCutOffAddr = strtoull(optarg, NULL, 0);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200380 break;
381 case 0x510:
382 hfuzz->dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
383 break;
384 case 0x511:
385 hfuzz->dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
386 break;
387 case 0x512:
Jagger3abc5602016-02-04 00:53:43 +0100388 hfuzz->dynFileMethod |= _HF_DYNFILE_BTS_BLOCK;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200389 break;
390 case 0x513:
Jagger3abc5602016-02-04 00:53:43 +0100391 hfuzz->dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200392 break;
393 case 0x514:
Jagger39bd2b02016-02-04 01:16:15 +0100394 hfuzz->dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
395 break;
Jagger39bd2b02016-02-04 01:16:15 +0100396 case 0x520:
Robert Swieckia88f96f2015-10-09 16:47:39 +0200397 hfuzz->dynFileMethod |= _HF_DYNFILE_CUSTOM;
398 break;
399 default:
400 cmdlineUsage(argv[0], custom_opts);
401 return false;
402 break;
403 }
404 }
Jagger72f258b2015-10-09 23:09:01 +0200405
Robert Swieckia88f96f2015-10-09 16:47:39 +0200406 if (logInitLogFile(logfile, ll) == false) {
407 return false;
408 }
409
410 hfuzz->cmdline = &argv[optind];
411 if (hfuzz->cmdline[0] == NULL) {
412 LOG_E("No fuzz command provided");
413 cmdlineUsage(argv[0], custom_opts);
414 return false;
415 }
416
Robert Swieckia88f96f2015-10-09 16:47:39 +0200417 if (!hfuzz->fuzzStdin && !checkFor_FILE_PLACEHOLDER(hfuzz->cmdline)) {
418 LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
419 "' when the -s (stdin fuzzing) option is not set");
420 return false;
421 }
422
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200423 if (hfuzz->dynFileMethod != _HF_DYNFILE_NONE && hfuzz->useSanCov) {
424 LOG_E("You cannot enable sanitizer coverage & perf feedback at the same time");
425 return false;
426 }
427
Anestis Bechtsoudisbd650542015-12-26 18:10:32 +0200428 /* Sanity checks for timeout. Optimal ranges highly depend on target */
429 if (hfuzz->useSanCov && hfuzz->tmOut < 15) {
Anestis Bechtsoudisebea8452015-12-26 18:05:40 +0200430 LOG_E("Timeout value (%ld) too small for sanitizer coverage feedback", hfuzz->tmOut);
431 return false;
432 }
433
Robert Swieckia88f96f2015-10-09 16:47:39 +0200434 if (strchr(hfuzz->fileExtn, '/')) {
435 LOG_E("The file extension contains the '/' character: '%s'", hfuzz->fileExtn);
436 return false;
437 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200438
Anestis Bechtsoudis8f4aa612015-12-27 12:06:19 +0200439 if (hfuzz->workDir[0] != '.' || strlen(hfuzz->workDir) > 2) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200440 if (!files_exists(hfuzz->workDir)) {
441 LOG_E("Provided workspace directory '%s' doesn't exist", hfuzz->workDir);
442 return false;
443 }
444 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200445
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200446 if (hfuzz->pid > 0 || hfuzz->pidFile) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200447 LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1", hfuzz->pid);
448 hfuzz->threadsMax = 1;
449 }
450
Robert Swieckia96d78d2016-03-14 16:50:50 +0100451 if (hfuzz->origFlipRate == 0.0L && hfuzz->useVerifier) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200452 LOG_I("Verifier enabled with 0.0 flipRate, activating dry run mode");
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200453 }
454
Robert Swieckia88f96f2015-10-09 16:47:39 +0200455 LOG_I("inputFile '%s', nullifyStdio: %s, fuzzStdin: %s, saveUnique: %s, flipRate: %lf, "
Anestis Bechtsoudisc9473322015-10-09 12:59:17 -0700456 "externalCommand: '%s', tmOut: %ld, mutationsMax: %zu, threadsMax: %zu, fileExtn '%s', ignoreAddr: %p, "
Robert Swieckia88f96f2015-10-09 16:47:39 +0200457 "memoryLimit: 0x%" PRIx64 "(MiB), fuzzExe: '%s', fuzzedPid: %d",
458 hfuzz->inputFile,
459 cmdlineYesNo(hfuzz->nullifyStdio), cmdlineYesNo(hfuzz->fuzzStdin),
Robert Swieckia96d78d2016-03-14 16:50:50 +0100460 cmdlineYesNo(hfuzz->saveUnique), hfuzz->origFlipRate,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200461 hfuzz->externalCommand == NULL ? "NULL" : hfuzz->externalCommand, hfuzz->tmOut,
462 hfuzz->mutationsMax, hfuzz->threadsMax, hfuzz->fileExtn, hfuzz->ignoreAddr,
463 hfuzz->asLimit, hfuzz->cmdline[0], hfuzz->pid);
464
Robert Swiecki2aaa52b2016-01-19 14:40:47 +0100465 snprintf(hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), "%s", hfuzz->cmdline[0]);
Robert Swiecki72d2bef2016-01-19 14:39:26 +0100466 for (size_t i = 1; hfuzz->cmdline[i]; i++) {
467 util_ssnprintf(hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), " %s", hfuzz->cmdline[i]);
468 }
469
Robert Swieckia88f96f2015-10-09 16:47:39 +0200470 return true;
471}