blob: 2a8d485d31fb26545c75aba2c52302fe26062ad5 [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 Swieckia88f96f2015-10-09 16:47:39 +020033#include <unistd.h>
34
35#include "common.h"
36#include "log.h"
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +020037#include "files.h"
Robert Swieckia88f96f2015-10-09 16:47:39 +020038
39#define AB ANSI_BOLD
40#define AC ANSI_CLEAR
41#define ANSI_BOLD "\033[1m"
42#define ANSI_CLEAR "\033[0m"
43
44struct custom_option {
45 struct option opt;
46 const char *descr;
47};
48
49static bool checkFor_FILE_PLACEHOLDER(char **args)
50{
51 for (int x = 0; args[x]; x++) {
52 if (strstr(args[x], _HF_FILE_PLACEHOLDER))
53 return true;
54 }
55 return false;
56}
57
58static const char *cmdlineYesNo(bool yes)
59{
60 return (yes ? "true" : "false");
61}
62
63static void cmdlineHelp(const char *pname, struct custom_option *opts)
64{
65 LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
66 LOG_HELP_BOLD("Options:");
67 for (int i = 0; opts[i].opt.name; i++) {
68 if (isprint(opts[i].opt.val)) {
69 LOG_HELP_BOLD(" --%s%s%c %s", opts[i].opt.name,
70 "|-", opts[i].opt.val,
71 opts[i].opt.has_arg == required_argument ? "[val]" : "");
72 } else {
73 LOG_HELP_BOLD(" --%s %s", opts[i].opt.name,
74 opts[i].opt.has_arg == required_argument ? "[val]" : "");
75 }
76 LOG_HELP("\t%s", opts[i].descr);
77 }
Jagger32127372015-10-09 23:07:38 +020078 LOG_HELP_BOLD("\nExamples:");
79 LOG_HELP(" Run the binary over a mutated file chosen from the directory");
80 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
81 LOG_HELP(" As above, provide input over STDIN:");
82 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -s -- /usr/bin/djpeg" AC);
Robert Swieckia88f96f2015-10-09 16:47:39 +020083#if defined(_HF_ARCH_LINUX)
Jagger32127372015-10-09 23:07:38 +020084 LOG_HELP(" Run the binary over a dynamic file, maximize total no. of instructions:");
Jagger72f258b2015-10-09 23:09:01 +020085 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_instr -- /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 total no. of branches:");
Jagger72f258b2015-10-09 23:09:01 +020088 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_branch -- /usr/bin/tiffinfo -D "
89 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020090 LOG_HELP(" Run the binary over a dynamic file, maximize unique code blocks (coverage):");
91 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
92 LOG_HELP(" Run the binary over a dynamic file, maximize unique branches (edges):");
Jagger72f258b2015-10-09 23:09:01 +020093 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip_addr -- /usr/bin/tiffinfo -D "
94 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020095 LOG_HELP(" Run the binary over a dynamic file, maximize custom counters (experimental):");
Jagger72f258b2015-10-09 23:09:01 +020096 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_custom -- /usr/bin/tiffinfo -D "
97 _HF_FILE_PLACEHOLDER);
Robert Swieckia88f96f2015-10-09 16:47:39 +020098#endif /* defined(_HF_ARCH_LINUX) */
Robert Swieckia88f96f2015-10-09 16:47:39 +020099}
100
101static void cmdlineUsage(const char *pname, struct custom_option *opts)
102{
103 cmdlineHelp(pname, opts);
104 exit(0);
105}
106
107static bool cmdlineIsANumber(const char *s)
108{
Jagger9c4d1622015-10-16 01:40:17 +0200109 if (!isdigit(s[0])) {
110 return false;
111 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200112 for (int i = 0; s[i]; s++) {
113 if (!isdigit(s[i]) && s[i] != 'x') {
114 return false;
115 }
116 }
117 return true;
118}
119
120rlim_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul)
121{
122 struct rlimit cur;
123 if (getrlimit(res, &cur) == -1) {
124 PLOG_F("getrlimit(%d)", res);
125 }
126 if (strcasecmp(optarg, "max") == 0) {
127 return cur.rlim_max;
128 }
129 if (strcasecmp(optarg, "def") == 0) {
130 return cur.rlim_cur;
131 }
132 if (cmdlineIsANumber(optarg) == false) {
133 LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
134 }
135 rlim_t val = strtoul(optarg, NULL, 0) * mul;
Jagger2bd61b72015-10-10 05:23:32 +0200136 if ((unsigned long)val == ULONG_MAX && errno != 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200137 PLOG_F("strtoul('%s', 0)", optarg);
138 }
139 return val;
140}
141
142bool cmdlineParse(int argc, char *argv[], honggfuzz_t * hfuzz)
143{
144 /* *INDENT-OFF* */
145 (*hfuzz) = (honggfuzz_t) {
146 .cmdline = NULL,
147 .inputFile = NULL,
148 .nullifyStdio = false,
149 .useScreen = true,
150 .fuzzStdin = false,
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700151 .useVerifier = false,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200152 .saveUnique = true,
153 .fileExtn = "fuzz",
154 .workDir = ".",
155 .flipRate = 0.001f,
156 .externalCommand = NULL,
157 .dictionaryFile = NULL,
158 .dictionary = NULL,
159 .dictionaryCnt = 0,
160 .blacklistFile = NULL,
161 .blacklistCnt = 0,
162 .blacklist = NULL,
163 .maxFileSz = (1024 * 1024),
164 .tmOut = 3,
165 .mutationsMax = 0,
166 .threadsFinished = 0,
167 .threadsMax = 2,
168 .reportFile = NULL,
169 .asLimit = 0ULL,
170 .files = NULL,
171 .fileCnt = 0,
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200172 .lastCheckedFileIndex = 0,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200173 .pid = 0,
174 .envs = {[0 ... (ARRAYSIZE(hfuzz->envs) - 1)] = NULL,},
175
176 .timeStart = time(NULL),
177 .mutationsCnt = 0,
178 .crashesCnt = 0,
179 .uniqueCrashesCnt = 0,
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200180 .verifiedCrashesCnt = 0,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200181 .blCrashesCnt = 0,
182 .timeoutedCnt = 0,
183
184 .dynFileMethod = _HF_DYNFILE_NONE,
185 .dynamicFileBest = NULL,
186 .dynamicFileBestSz = 1,
187 .hwCnts = {
188 .cpuInstrCnt = 0ULL,
189 .cpuBranchCnt = 0ULL,
190 .pcCnt = 0ULL,
191 .pathCnt = 0ULL,
192 .customCnt = 0ULL,
193 },
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200194 .sanCovCnts = {
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200195 .hitPcCnt = 0ULL,
196 .totalPcCnt = 0ULL,
197 .dsoCnt = 0ULL,
198 .iDsoCnt = 0ULL,
199 .newPcCnt = 0ULL,
200 .crashesCnt = 0ULL,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200201 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200202 .dynamicCutOffAddr = ~(0ULL),
203 .dynamicFile_mutex = PTHREAD_MUTEX_INITIALIZER,
204
205 .disableRandomization = true,
206 .msanReportUMRS = false,
207 .ignoreAddr = NULL,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200208 .useSanCov = false,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200209 .covMetadata = NULL,
Anestis Bechtsoudis1fd10c72016-01-07 12:38:45 +0200210 .clearCovMetadata = false,
Anestis Bechtsoudis02b99be2015-12-27 11:53:01 +0200211 .dynFileIterExpire = _HF_MAX_DYNFILE_ITER,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200212 .sanCov_mutex = PTHREAD_MUTEX_INITIALIZER,
Anestis Bechtsoudisac054802016-01-07 23:48:06 +0200213 .workersBlock_mutex = PTHREAD_MUTEX_INITIALIZER,
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200214 .sanOpts = {
215 .asanOpts = NULL,
216 .msanOpts = NULL,
217 .ubsanOpts = NULL,
218 },
219 .numMajorFrames = 7,
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200220#ifdef _HF_DEBUG
221 .maxSpentInSanCov = 0,
222#endif
Robert Swieckia88f96f2015-10-09 16:47:39 +0200223 };
224 /* *INDENT-ON* */
225
226 /* *INDENT-OFF* */
227 struct custom_option custom_opts[] = {
228 {{"help", no_argument, NULL, 'h'}, "Help plz.."},
229 {{"input", required_argument, NULL, 'f'}, "Path to the file corpus (file or a directory)"},
230 {{"nullify_stdio", no_argument, NULL, 'q'}, "Null-ify children's stdin, stdout, stderr; make them quiet"},
231 {{"stdin_input", no_argument, NULL, 's'}, "Provide fuzzing input on STDIN, instead of ___FILE___"},
232 {{"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 +0200233 {{"logfile", required_argument, NULL, 'l'}, "Log file"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200234 {{"verbose", no_argument, NULL, 'v'}, "Disable ANSI console; use simple log output"},
Anestis Bechtsoudis4a3c8e82015-11-07 18:59:14 +0200235#if defined(_HF_ARCH_LINUX) || defined(_HF_ARCH_DARWIN)
Anestis Bechtsoudis15744be2015-10-31 22:33:31 +0200236 {{"verifier", no_argument, NULL, 'V'}, "Enable crashes verifier (default: disabled)"},
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700237#endif
Robert Swieckia88f96f2015-10-09 16:47:39 +0200238 {{"debug_level", required_argument, NULL, 'd'}, "Debug level (0 - FATAL ... 4 - DEBUG), (default: '3' [INFO])"},
239 {{"extension", required_argument, NULL, 'e'}, "Input file extension (e.g. 'swf'), (default: 'fuzz')"},
240 {{"wokspace", required_argument, NULL, 'W'}, "Workspace directory to save crashes & runtime files (default: '.')"},
241 {{"flip_rate", required_argument, NULL, 'r'}, "Maximal flip rate, (default: '0.001')"},
242 {{"wordlist", required_argument, NULL, 'w'}, "Wordlist file (tokens delimited by NUL-bytes)"},
243 {{"stackhash_bl", required_argument, NULL, 'B'}, "Stackhashes blacklist file (one entry per line)"},
244 {{"mutate_cmd", required_argument, NULL, 'c'}, "External command modifying the input corpus of files, instead of -r/-m parameters"},
245 {{"timeout", required_argument, NULL, 't'}, "Timeout in seconds (default: '3')"},
246 {{"threads", required_argument, NULL, 'n'}, "Number of concurrent fuzzing threads (default: '2')"},
247 {{"iterations", required_argument, NULL, 'N'}, "Number of fuzzing iterations (default: '0' [no limit])"},
Robert Swiecki03ef5312015-10-09 18:25:40 +0200248 {{"rlimit_as", required_argument, NULL, 0x100}, "Per process memory limit in MiB (default: '0' [no limit])"},
dyjakanebfd24e2015-10-16 19:24:32 +0100249 {{"report", required_argument, NULL, 'R'}, "Write report to this file (default: '" _HF_REPORT_FILE "')"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200250 {{"max_file_size", required_argument, NULL, 'F'}, "Maximal size of files processed by the fuzzer in bytes (default: '1048576')"},
251 {{"env", required_argument, NULL, 'E'}, "Pass this environment variable, can be used multiple times"},
252
253#if defined(_HF_ARCH_LINUX)
Anestis Bechtsoudis55329342015-12-26 18:08:24 +0200254 {{"sancov", no_argument, NULL, 'C'}, "EXPERIMENTAL: Enable sanitizer coverage feedback (default: disabled)"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200255 {{"linux_pid", required_argument, NULL, 'p'}, "[Linux] Attach to a pid (and its thread group)"},
256 {{"linux_addr_low_limit", required_argument, NULL, 0x500}, "Address limit (from si.si_addr) below which crashes are not reported, (default: '0')"},
257 {{"linux_keep_aslr", no_argument, NULL, 0x501}, "Don't disable ASLR randomization, might be useful with MSAN"},
258 {{"linux_report_msan_umrs", no_argument, NULL, 0x502}, "Report MSAN's UMRS (uninitialized memory access)"},
Jaggerae6a4452015-10-14 17:34:43 +0200259 {{"linux_perf_ignore_above", required_argument, NULL, 0x503}, "Ignore perf events which report IPs above this address"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200260 {{"linux_perf_instr", no_argument, NULL, 0x510}, "Use PERF_COUNT_HW_INSTRUCTIONS perf"},
261 {{"linux_perf_branch", no_argument, NULL, 0x511}, "Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf"},
262 {{"linux_perf_ip", no_argument, NULL, 0x512}, "Use PERF_SAMPLE_IP perf (newer Intel CPUs only)"},
263 {{"linux_perf_ip_addr", no_argument, NULL, 0x513}, "Use PERF_SAMPLE_IP/PERF_SAMPLE_ADDR perf (newer Intel CPUs only)"},
264 {{"linux_perf_custom", no_argument, NULL, 0x514}, "Custom counter (see the interceptor/ directory for examples)"},
265#endif // defined(_HF_ARCH_LINUX)
266 {{0, 0, 0, 0}, NULL},
267 };
268 /* *INDENT-ON* */
269
270 struct option opts[ARRAYSIZE(custom_opts)];
271 for (unsigned i = 0; i < ARRAYSIZE(custom_opts); i++) {
272 opts[i] = custom_opts[i].opt;
273 }
274
275 enum llevel_t ll = INFO;
276 const char *logfile = NULL;
277 int opt_index = 0;
278 for (;;) {
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200279 int c = getopt_long(argc, argv, "-?hqvVsuf:d:e:W:r:c:F:t:R:n:N:l:p:g:E:w:B:C", opts,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200280 &opt_index);
281 if (c < 0)
282 break;
283
284 switch (c) {
285 case 'h':
286 case '?':
287 cmdlineUsage(argv[0], custom_opts);
288 break;
289 case 'f':
290 hfuzz->inputFile = optarg;
291 break;
292 case 'q':
293 hfuzz->nullifyStdio = true;
294 break;
295 case 'v':
296 hfuzz->useScreen = false;
297 break;
Anestis Bechtsoudis0cde66f2015-10-11 19:37:11 -0700298 case 'V':
299 hfuzz->useVerifier = true;
300 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200301 case 's':
302 hfuzz->fuzzStdin = true;
303 break;
304 case 'u':
305 hfuzz->saveUnique = false;
306 break;
Robert Swiecki03ef5312015-10-09 18:25:40 +0200307 case 'l':
308 logfile = optarg;
309 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200310 case 'd':
311 ll = atoi(optarg);
312 break;
313 case 'e':
314 hfuzz->fileExtn = optarg;
315 break;
316 case 'W':
317 hfuzz->workDir = optarg;
318 break;
319 case 'r':
320 hfuzz->flipRate = strtod(optarg, NULL);
321 break;
322 case 'c':
323 hfuzz->externalCommand = optarg;
324 break;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200325 case 'C':
326 hfuzz->useSanCov = true;
327 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200328 case 'F':
329 hfuzz->maxFileSz = strtoul(optarg, NULL, 0);
330 break;
331 case 't':
332 hfuzz->tmOut = atol(optarg);
333 break;
334 case 'R':
335 hfuzz->reportFile = optarg;
336 break;
337 case 'n':
338 hfuzz->threadsMax = atol(optarg);
339 break;
340 case 'N':
341 hfuzz->mutationsMax = atol(optarg);
342 break;
Robert Swiecki03ef5312015-10-09 18:25:40 +0200343 case 0x100:
Robert Swieckia88f96f2015-10-09 16:47:39 +0200344 hfuzz->asLimit = strtoull(optarg, NULL, 0);
345 break;
346 case 'p':
Jagger9c4d1622015-10-16 01:40:17 +0200347 if (cmdlineIsANumber(optarg) == false) {
348 LOG_E("-p '%s' is not a number", optarg);
349 return false;
350 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200351 hfuzz->pid = atoi(optarg);
Jagger9c4d1622015-10-16 01:40:17 +0200352 if (hfuzz->pid < 1) {
353 LOG_E("-p '%d' is invalid", hfuzz->pid);
354 return false;
355 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200356 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200357 case 'E':
358 for (size_t i = 0; i < ARRAYSIZE(hfuzz->envs); i++) {
359 if (hfuzz->envs[i] == NULL) {
360 hfuzz->envs[i] = optarg;
361 break;
362 }
363 }
364 break;
365 case 'w':
366 hfuzz->dictionaryFile = optarg;
367 break;
368 case 'B':
369 hfuzz->blacklistFile = optarg;
370 break;
371 case 0x500:
372 hfuzz->ignoreAddr = (void *)strtoul(optarg, NULL, 0);
373 break;
374 case 0x501:
375 hfuzz->disableRandomization = false;
376 break;
377 case 0x502:
378 hfuzz->msanReportUMRS = true;
379 break;
380 case 0x503:
Jagger0b21ebb2015-10-14 17:39:15 +0200381 hfuzz->dynamicCutOffAddr = strtoull(optarg, NULL, 0);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200382 break;
383 case 0x510:
384 hfuzz->dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
385 break;
386 case 0x511:
387 hfuzz->dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
388 break;
389 case 0x512:
390 hfuzz->dynFileMethod |= _HF_DYNFILE_UNIQUE_BLOCK_COUNT;
391 break;
392 case 0x513:
393 hfuzz->dynFileMethod |= _HF_DYNFILE_UNIQUE_EDGE_COUNT;
394 break;
395 case 0x514:
396 hfuzz->dynFileMethod |= _HF_DYNFILE_CUSTOM;
397 break;
398 default:
399 cmdlineUsage(argv[0], custom_opts);
400 return false;
401 break;
402 }
403 }
Jagger72f258b2015-10-09 23:09:01 +0200404
Robert Swieckia88f96f2015-10-09 16:47:39 +0200405 if (logInitLogFile(logfile, ll) == false) {
406 return false;
407 }
408
409 hfuzz->cmdline = &argv[optind];
410 if (hfuzz->cmdline[0] == NULL) {
411 LOG_E("No fuzz command provided");
412 cmdlineUsage(argv[0], custom_opts);
413 return false;
414 }
415
416 if (hfuzz->dynamicFileBestSz > hfuzz->maxFileSz) {
417 LOG_E("Initial dynamic file size cannot be larger than maximum file size (%zu > %zu)",
418 hfuzz->dynamicFileBestSz, hfuzz->maxFileSz);
419 return false;
420 }
421
422 if ((hfuzz->dynamicFileBest = malloc(hfuzz->maxFileSz)) == NULL) {
423 LOG_E("malloc(%zu) failed", hfuzz->maxFileSz);
424 return false;
425 }
426
427 if (!hfuzz->fuzzStdin && !checkFor_FILE_PLACEHOLDER(hfuzz->cmdline)) {
428 LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
429 "' when the -s (stdin fuzzing) option is not set");
430 return false;
431 }
432
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200433 if (hfuzz->dynFileMethod != _HF_DYNFILE_NONE && hfuzz->useSanCov) {
434 LOG_E("You cannot enable sanitizer coverage & perf feedback at the same time");
435 return false;
436 }
437
Anestis Bechtsoudisbd650542015-12-26 18:10:32 +0200438 /* Sanity checks for timeout. Optimal ranges highly depend on target */
439 if (hfuzz->useSanCov && hfuzz->tmOut < 15) {
Anestis Bechtsoudisebea8452015-12-26 18:05:40 +0200440 LOG_E("Timeout value (%ld) too small for sanitizer coverage feedback", hfuzz->tmOut);
441 return false;
442 }
443
Robert Swieckia88f96f2015-10-09 16:47:39 +0200444 if (strchr(hfuzz->fileExtn, '/')) {
445 LOG_E("The file extension contains the '/' character: '%s'", hfuzz->fileExtn);
446 return false;
447 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200448
Anestis Bechtsoudis8f4aa612015-12-27 12:06:19 +0200449 if (hfuzz->workDir[0] != '.' || strlen(hfuzz->workDir) > 2) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200450 if (!files_exists(hfuzz->workDir)) {
451 LOG_E("Provided workspace directory '%s' doesn't exist", hfuzz->workDir);
452 return false;
453 }
454 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200455
456 if (hfuzz->pid > 0) {
457 LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1", hfuzz->pid);
458 hfuzz->threadsMax = 1;
459 }
460
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200461 if (hfuzz->flipRate == 0.0L && hfuzz->useVerifier) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200462 LOG_I("Verifier enabled with 0.0 flipRate, activating dry run mode");
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200463 }
464
Robert Swieckia88f96f2015-10-09 16:47:39 +0200465 LOG_I("inputFile '%s', nullifyStdio: %s, fuzzStdin: %s, saveUnique: %s, flipRate: %lf, "
Anestis Bechtsoudisc9473322015-10-09 12:59:17 -0700466 "externalCommand: '%s', tmOut: %ld, mutationsMax: %zu, threadsMax: %zu, fileExtn '%s', ignoreAddr: %p, "
Robert Swieckia88f96f2015-10-09 16:47:39 +0200467 "memoryLimit: 0x%" PRIx64 "(MiB), fuzzExe: '%s', fuzzedPid: %d",
468 hfuzz->inputFile,
469 cmdlineYesNo(hfuzz->nullifyStdio), cmdlineYesNo(hfuzz->fuzzStdin),
470 cmdlineYesNo(hfuzz->saveUnique), hfuzz->flipRate,
471 hfuzz->externalCommand == NULL ? "NULL" : hfuzz->externalCommand, hfuzz->tmOut,
472 hfuzz->mutationsMax, hfuzz->threadsMax, hfuzz->fileExtn, hfuzz->ignoreAddr,
473 hfuzz->asLimit, hfuzz->cmdline[0], hfuzz->pid);
474
475 return true;
476}