blob: a78c23af4585d0a886835bdccbebcbea6f2b9c99 [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++) {
Robert Swieckif3a5f6a2016-03-16 14:47:30 +010065 if (isprint(opts[i].opt.val) && opts[i].opt.val < 0x80) {
Robert Swieckia88f96f2015-10-09 16:47:39 +020066 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");
Jaggerba92b4b2016-03-16 02:24:17 +010080 LOG_HELP(" Use SANCOV to maximize code coverage:");
81 LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -C -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
Robert Swieckia88f96f2015-10-09 16:47:39 +020082#if defined(_HF_ARCH_LINUX)
Jagger32127372015-10-09 23:07:38 +020083 LOG_HELP(" Run the binary over a dynamic file, maximize total no. of instructions:");
Jagger72f258b2015-10-09 23:09:01 +020084 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_instr -- /usr/bin/tiffinfo -D "
85 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020086 LOG_HELP(" Run the binary over a dynamic file, maximize total no. of branches:");
Jagger72f258b2015-10-09 23:09:01 +020087 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_branch -- /usr/bin/tiffinfo -D "
88 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020089 LOG_HELP(" Run the binary over a dynamic file, maximize unique code blocks (coverage):");
90 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip -- /usr/bin/tiffinfo -D " _HF_FILE_PLACEHOLDER);
91 LOG_HELP(" Run the binary over a dynamic file, maximize unique branches (edges):");
Jagger72f258b2015-10-09 23:09:01 +020092 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_ip_addr -- /usr/bin/tiffinfo -D "
93 _HF_FILE_PLACEHOLDER);
Jagger32127372015-10-09 23:07:38 +020094 LOG_HELP(" Run the binary over a dynamic file, maximize custom counters (experimental):");
Jagger72f258b2015-10-09 23:09:01 +020095 LOG_HELP_BOLD(" " PROG_NAME " --linux_perf_custom -- /usr/bin/tiffinfo -D "
96 _HF_FILE_PLACEHOLDER);
Robert Swieckia88f96f2015-10-09 16:47:39 +020097#endif /* defined(_HF_ARCH_LINUX) */
Robert Swieckia88f96f2015-10-09 16:47:39 +020098}
99
100static void cmdlineUsage(const char *pname, struct custom_option *opts)
101{
102 cmdlineHelp(pname, opts);
103 exit(0);
104}
105
Robert Swieckia88f96f2015-10-09 16:47:39 +0200106rlim_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul)
107{
108 struct rlimit cur;
109 if (getrlimit(res, &cur) == -1) {
110 PLOG_F("getrlimit(%d)", res);
111 }
112 if (strcasecmp(optarg, "max") == 0) {
113 return cur.rlim_max;
114 }
115 if (strcasecmp(optarg, "def") == 0) {
116 return cur.rlim_cur;
117 }
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200118 if (util_isANumber(optarg) == false) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200119 LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res, optarg);
120 }
121 rlim_t val = strtoul(optarg, NULL, 0) * mul;
Jagger2bd61b72015-10-10 05:23:32 +0200122 if ((unsigned long)val == ULONG_MAX && errno != 0) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200123 PLOG_F("strtoul('%s', 0)", optarg);
124 }
125 return val;
126}
127
128bool cmdlineParse(int argc, char *argv[], honggfuzz_t * hfuzz)
129{
130 /* *INDENT-OFF* */
131 (*hfuzz) = (honggfuzz_t) {
132 .cmdline = NULL,
Robert Swiecki72d2bef2016-01-19 14:39:26 +0100133 .cmdline_txt[0] = '\0',
Robert Swieckia88f96f2015-10-09 16:47:39 +0200134 .inputFile = NULL,
135 .nullifyStdio = false,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200136 .fuzzStdin = false,
137 .saveUnique = true,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100138 .useScreen = true,
139 .useVerifier = false,
140 .timeStart = time(NULL),
Robert Swieckia88f96f2015-10-09 16:47:39 +0200141 .fileExtn = "fuzz",
142 .workDir = ".",
Robert Swieckia96d78d2016-03-14 16:50:50 +0100143 .origFlipRate = 0.001f,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200144 .externalCommand = NULL,
145 .dictionaryFile = NULL,
146 .dictionary = NULL,
147 .dictionaryCnt = 0,
148 .blacklistFile = NULL,
149 .blacklistCnt = 0,
150 .blacklist = NULL,
151 .maxFileSz = (1024 * 1024),
Jaggerba92b4b2016-03-16 02:24:17 +0100152 .tmOut = 10,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200153 .mutationsMax = 0,
154 .threadsFinished = 0,
155 .threadsMax = 2,
156 .reportFile = NULL,
157 .asLimit = 0ULL,
158 .files = NULL,
159 .fileCnt = 0,
Robert Swiecki05354ca2016-03-15 19:10:23 +0100160 .lastFileIndex = 0,
161 .doneFileIndex = 0,
Jaggercdbf6852016-02-07 22:06:02 +0100162 .exeFd = -1,
Jagger80041fe2016-03-10 21:32:35 +0100163 .clearEnv = false,
Jaggerab26e702016-03-22 04:28:00 +0100164 .envs = {
165 [0 ... (ARRAYSIZE(hfuzz->envs) - 1)] = NULL,
166 },
Robert Swiecki0f937af2016-03-30 18:19:16 +0200167 .persistent = false,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200168
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100169 .state = _HF_STATE_UNSET,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100170 .bbMapSz = _HF_PERF_BITMAP_SIZE,
Jagger2c8f7192016-03-19 02:17:22 +0100171 .bbMap = NULL,
Robert Swieckie586c1f2016-03-14 18:46:03 +0100172 .dynfileq_mutex = PTHREAD_MUTEX_INITIALIZER,
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100173 .dynfileqCnt = 0U,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100174
Robert Swieckia88f96f2015-10-09 16:47:39 +0200175 .mutationsCnt = 0,
176 .crashesCnt = 0,
177 .uniqueCrashesCnt = 0,
Anestis Bechtsoudis79b799e2015-11-01 00:02:25 +0200178 .verifiedCrashesCnt = 0,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200179 .blCrashesCnt = 0,
180 .timeoutedCnt = 0,
181
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100182 .dynFileMethod = _HF_DYNFILE_NONE,
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200183 .sanCovCnts = {
Jaggerab26e702016-03-22 04:28:00 +0100184 .hitBBCnt = 0ULL,
185 .totalBBCnt = 0ULL,
186 .dsoCnt = 0ULL,
187 .iDsoCnt = 0ULL,
188 .newBBCnt = 0ULL,
189 .crashesCnt = 0ULL,
190 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200191
Anestis Bechtsoudisa16f70f2016-01-03 13:03:21 +0200192 .sanCov_mutex = PTHREAD_MUTEX_INITIALIZER,
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100193 .sanOpts = {
Jaggerab26e702016-03-22 04:28:00 +0100194 .asanOpts = NULL,
195 .msanOpts = NULL,
196 .ubsanOpts = NULL,
Anestis Bechtsoudis61b5ab12016-01-08 16:07:02 +0200197 },
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100198 .useSanCov = false,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100199 .covMetadata = NULL,
Jagger247c3b42016-03-21 23:24:05 +0100200 .msanReportUMRS = false,
Robert Swiecki6c9f6822016-03-14 16:12:27 +0100201
202 /* Linux code */
Robert Swieckifab69162016-03-31 15:41:36 +0200203 .linux = {
Jaggerab26e702016-03-22 04:28:00 +0100204 .hwCnts = {
205 .cpuInstrCnt = 0ULL,
206 .cpuBranchCnt = 0ULL,
207 .customCnt = 0ULL,
208 .bbCnt = 0ULL,
209 .newBBCnt = 0ULL,
210 },
211 .dynamicCutOffAddr = ~(0ULL),
212 .disableRandomization = true,
213 .ignoreAddr = NULL,
214 .numMajorFrames = 7,
215 .pid = 0,
216 .pidFile = NULL,
217 .pidCmd = NULL,
218 },
Robert Swieckia88f96f2015-10-09 16:47:39 +0200219 };
220 /* *INDENT-ON* */
221
Robert Swiecki3bfc33c2016-03-14 18:12:41 +0100222 TAILQ_INIT(&hfuzz->dynfileq);
223
Robert Swieckia88f96f2015-10-09 16:47:39 +0200224 /* *INDENT-OFF* */
225 struct custom_option custom_opts[] = {
226 {{"help", no_argument, NULL, 'h'}, "Help plz.."},
227 {{"input", required_argument, NULL, 'f'}, "Path to the file corpus (file or a directory)"},
228 {{"nullify_stdio", no_argument, NULL, 'q'}, "Null-ify children's stdin, stdout, stderr; make them quiet"},
Jagger54c96a22016-03-30 23:13:30 +0200229 {{"timeout", required_argument, NULL, 't'}, "Timeout in seconds (default: '10')"},
230 {{"threads", required_argument, NULL, 'n'}, "Number of concurrent fuzzing threads (default: '2')"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200231 {{"stdin_input", no_argument, NULL, 's'}, "Provide fuzzing input on STDIN, instead of ___FILE___"},
Jagger54c96a22016-03-30 23:13:30 +0200232 {{"mutation_rate", required_argument, NULL, 'r'}, "Maximal mutation rate in relation to the file size, (default: '0.001')"},
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"},
Jagger5ff08ac2016-02-09 22:15:58 +0100235 {{"verifier", no_argument, NULL, 'V'}, "Enable crashes verifier"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200236 {{"debug_level", required_argument, NULL, 'd'}, "Debug level (0 - FATAL ... 4 - DEBUG), (default: '3' [INFO])"},
237 {{"extension", required_argument, NULL, 'e'}, "Input file extension (e.g. 'swf'), (default: 'fuzz')"},
Anestis Bechtsoudisbfcba122016-04-28 10:55:20 +0300238 {{"workspace", required_argument, NULL, 'W'}, "Workspace directory to save crashes & runtime files (default: '.')"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200239 {{"wordlist", required_argument, NULL, 'w'}, "Wordlist file (tokens delimited by NUL-bytes)"},
240 {{"stackhash_bl", required_argument, NULL, 'B'}, "Stackhashes blacklist file (one entry per line)"},
Anestis Bechtsoudisbfcba122016-04-28 10:55:20 +0300241 {{"mutate_cmd", required_argument, NULL, 'c'}, "External command providing fuzz files, instead of mutating the input corpus"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200242 {{"iterations", required_argument, NULL, 'N'}, "Number of fuzzing iterations (default: '0' [no limit])"},
Robert Swiecki03ef5312015-10-09 18:25:40 +0200243 {{"rlimit_as", required_argument, NULL, 0x100}, "Per process memory limit in MiB (default: '0' [no limit])"},
dyjakanebfd24e2015-10-16 19:24:32 +0100244 {{"report", required_argument, NULL, 'R'}, "Write report to this file (default: '" _HF_REPORT_FILE "')"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200245 {{"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 +0100246 {{"clear_env", no_argument, NULL, 0x101}, "Clear all environment variables before executing the binary"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200247 {{"env", required_argument, NULL, 'E'}, "Pass this environment variable, can be used multiple times"},
Jagger54c96a22016-03-30 23:13:30 +0200248 {{"save_all", no_argument, NULL, 'u'}, "Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames"},
Jagger3db1d952016-03-10 02:02:46 +0100249 {{"sancov", no_argument, NULL, 'C'}, "Enable sanitizer coverage feedback"},
Jagger7ff92fa2016-03-22 04:13:50 +0100250 {{"msan_report_umrs", no_argument, NULL, 0x102}, "Report MSAN's UMRS (uninitialized memory access)"},
Robert Swieckifab69162016-03-31 15:41:36 +0200251 {{"persistent", no_argument, NULL, 'P'}, "Enable persistent fuzzing (link with tools/persistent.mode.main.c)"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200252
253#if defined(_HF_ARCH_LINUX)
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200254 {{"linux_pid", required_argument, NULL, 'p'}, "Attach to a pid (and its thread group)"},
Robert Swieckifab69162016-03-31 15:41:36 +0200255 {{"linux_file_pid", required_argument, NULL, 0x502}, "Attach to pid (and its thread group) read from file"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200256 {{"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"},
Jaggerae6a4452015-10-14 17:34:43 +0200258 {{"linux_perf_ignore_above", required_argument, NULL, 0x503}, "Ignore perf events which report IPs above this address"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200259 {{"linux_perf_instr", no_argument, NULL, 0x510}, "Use PERF_COUNT_HW_INSTRUCTIONS perf"},
260 {{"linux_perf_branch", no_argument, NULL, 0x511}, "Use PERF_COUNT_HW_BRANCH_INSTRUCTIONS perf"},
Jagger39bd2b02016-02-04 01:16:15 +0100261 {{"linux_perf_bts_block", no_argument, NULL, 0x512}, "Use Intel BTS to count unique blocks"},
262 {{"linux_perf_bts_edge", no_argument, NULL, 0x513}, "Use Intel BTS to count unique edges"},
263 {{"linux_perf_ipt_block", no_argument, NULL, 0x514}, "Use Intel Processor Trace to count unique blocks"},
Jaggerad2b3c12016-04-02 00:06:37 +0200264 {{"linux_perf_custom", no_argument, NULL, 0x520}, "Custom counter (see interceptor/stringmem.c)"},
Robert Swieckia88f96f2015-10-09 16:47:39 +0200265#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 (;;) {
Robert Swieckifab69162016-03-31 15:41:36 +0200279 int c = getopt_long(argc, argv, "-?hqvVsuPf: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':
Robert Swieckia96d78d2016-03-14 16:50:50 +0100320 hfuzz->origFlipRate = strtod(optarg, NULL);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200321 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;
Jagger80041fe2016-03-10 21:32:35 +0100346 case 0x101:
347 hfuzz->clearEnv = true;
348 break;
Jagger7ff92fa2016-03-22 04:13:50 +0100349 case 0x102:
350 hfuzz->msanReportUMRS = true;
351 break;
Robert Swieckifab69162016-03-31 15:41:36 +0200352 case 'P':
Robert Swiecki0f937af2016-03-30 18:19:16 +0200353 hfuzz->persistent = true;
354 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200355 case 'p':
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200356 if (util_isANumber(optarg) == false) {
Jagger9c4d1622015-10-16 01:40:17 +0200357 LOG_E("-p '%s' is not a number", optarg);
358 return false;
359 }
Jagger247c3b42016-03-21 23:24:05 +0100360 hfuzz->linux.pid = atoi(optarg);
361 if (hfuzz->linux.pid < 1) {
362 LOG_E("-p '%d' is invalid", hfuzz->linux.pid);
Jagger9c4d1622015-10-16 01:40:17 +0200363 return false;
364 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200365 break;
Robert Swieckifab69162016-03-31 15:41:36 +0200366 case 0x502:
Jagger247c3b42016-03-21 23:24:05 +0100367 hfuzz->linux.pidFile = optarg;
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200368 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200369 case 'E':
370 for (size_t i = 0; i < ARRAYSIZE(hfuzz->envs); i++) {
371 if (hfuzz->envs[i] == NULL) {
372 hfuzz->envs[i] = optarg;
373 break;
374 }
375 }
376 break;
377 case 'w':
378 hfuzz->dictionaryFile = optarg;
379 break;
380 case 'B':
381 hfuzz->blacklistFile = optarg;
382 break;
383 case 0x500:
Jagger247c3b42016-03-21 23:24:05 +0100384 hfuzz->linux.ignoreAddr = (void *)strtoul(optarg, NULL, 0);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200385 break;
386 case 0x501:
Jagger247c3b42016-03-21 23:24:05 +0100387 hfuzz->linux.disableRandomization = false;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200388 break;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200389 case 0x503:
Jagger247c3b42016-03-21 23:24:05 +0100390 hfuzz->linux.dynamicCutOffAddr = strtoull(optarg, NULL, 0);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200391 break;
392 case 0x510:
393 hfuzz->dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
394 break;
395 case 0x511:
396 hfuzz->dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
397 break;
398 case 0x512:
Jagger3abc5602016-02-04 00:53:43 +0100399 hfuzz->dynFileMethod |= _HF_DYNFILE_BTS_BLOCK;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200400 break;
401 case 0x513:
Jagger3abc5602016-02-04 00:53:43 +0100402 hfuzz->dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
Robert Swieckia88f96f2015-10-09 16:47:39 +0200403 break;
404 case 0x514:
Jagger39bd2b02016-02-04 01:16:15 +0100405 hfuzz->dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
406 break;
Jagger39bd2b02016-02-04 01:16:15 +0100407 case 0x520:
Robert Swieckia88f96f2015-10-09 16:47:39 +0200408 hfuzz->dynFileMethod |= _HF_DYNFILE_CUSTOM;
409 break;
410 default:
411 cmdlineUsage(argv[0], custom_opts);
412 return false;
413 break;
414 }
415 }
Jagger72f258b2015-10-09 23:09:01 +0200416
Robert Swieckia88f96f2015-10-09 16:47:39 +0200417 if (logInitLogFile(logfile, ll) == false) {
418 return false;
419 }
420
421 hfuzz->cmdline = &argv[optind];
422 if (hfuzz->cmdline[0] == NULL) {
423 LOG_E("No fuzz command provided");
424 cmdlineUsage(argv[0], custom_opts);
425 return false;
426 }
427
Robert Swiecki0f937af2016-03-30 18:19:16 +0200428 if (!hfuzz->fuzzStdin && !hfuzz->persistent && !checkFor_FILE_PLACEHOLDER(hfuzz->cmdline)) {
Robert Swieckia88f96f2015-10-09 16:47:39 +0200429 LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
Robert Swiecki0f937af2016-03-30 18:19:16 +0200430 "' when the -s (stdin fuzzing) or --persistent options are not set");
Robert Swieckia88f96f2015-10-09 16:47:39 +0200431 return false;
432 }
433
Anestis Bechtsoudisbd650542015-12-26 18:10:32 +0200434 /* Sanity checks for timeout. Optimal ranges highly depend on target */
Jaggerba92b4b2016-03-16 02:24:17 +0100435 if (hfuzz->useSanCov && hfuzz->tmOut < 10) {
436 LOG_E("Timeout value (%ld) too small for sanitizer coverage feedback", (long)hfuzz->tmOut);
Anestis Bechtsoudisebea8452015-12-26 18:05:40 +0200437 return false;
438 }
439
Robert Swieckia88f96f2015-10-09 16:47:39 +0200440 if (strchr(hfuzz->fileExtn, '/')) {
441 LOG_E("The file extension contains the '/' character: '%s'", hfuzz->fileExtn);
442 return false;
443 }
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200444
Anestis Bechtsoudis8f4aa612015-12-27 12:06:19 +0200445 if (hfuzz->workDir[0] != '.' || strlen(hfuzz->workDir) > 2) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200446 if (!files_exists(hfuzz->workDir)) {
447 LOG_E("Provided workspace directory '%s' doesn't exist", hfuzz->workDir);
448 return false;
449 }
450 }
Robert Swieckia88f96f2015-10-09 16:47:39 +0200451
Jagger247c3b42016-03-21 23:24:05 +0100452 if (hfuzz->linux.pid > 0 || hfuzz->linux.pidFile) {
453 LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1",
454 hfuzz->linux.pid);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200455 hfuzz->threadsMax = 1;
456 }
457
Robert Swieckia96d78d2016-03-14 16:50:50 +0100458 if (hfuzz->origFlipRate == 0.0L && hfuzz->useVerifier) {
Anestis Bechtsoudisc8e7f6e2015-12-26 14:48:48 +0200459 LOG_I("Verifier enabled with 0.0 flipRate, activating dry run mode");
Anestis Bechtsoudis46ea10e2015-11-07 18:16:25 +0200460 }
461
Robert Swieckia88f96f2015-10-09 16:47:39 +0200462 LOG_I("inputFile '%s', nullifyStdio: %s, fuzzStdin: %s, saveUnique: %s, flipRate: %lf, "
Jagger247c3b42016-03-21 23:24:05 +0100463 "externalCommand: '%s', tmOut: %ld, mutationsMax: %zu, threadsMax: %zu, fileExtn '%s', "
Robert Swieckia88f96f2015-10-09 16:47:39 +0200464 "memoryLimit: 0x%" PRIx64 "(MiB), fuzzExe: '%s', fuzzedPid: %d",
465 hfuzz->inputFile,
466 cmdlineYesNo(hfuzz->nullifyStdio), cmdlineYesNo(hfuzz->fuzzStdin),
Robert Swieckia96d78d2016-03-14 16:50:50 +0100467 cmdlineYesNo(hfuzz->saveUnique), hfuzz->origFlipRate,
Robert Swieckia88f96f2015-10-09 16:47:39 +0200468 hfuzz->externalCommand == NULL ? "NULL" : hfuzz->externalCommand, hfuzz->tmOut,
Jagger247c3b42016-03-21 23:24:05 +0100469 hfuzz->mutationsMax, hfuzz->threadsMax, hfuzz->fileExtn,
470 hfuzz->asLimit, hfuzz->cmdline[0], hfuzz->linux.pid);
Robert Swieckia88f96f2015-10-09 16:47:39 +0200471
Robert Swiecki2aaa52b2016-01-19 14:40:47 +0100472 snprintf(hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), "%s", hfuzz->cmdline[0]);
Robert Swiecki72d2bef2016-01-19 14:39:26 +0100473 for (size_t i = 1; hfuzz->cmdline[i]; i++) {
474 util_ssnprintf(hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), " %s", hfuzz->cmdline[i]);
475 }
476
Robert Swieckia88f96f2015-10-09 16:47:39 +0200477 return true;
478}