1 /*
2    american fuzzy lop++ - fuzzer code
3    --------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <mh@mh-sec.de>,
8                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
9                         Andrea Fioraldi <andreafioraldi@gmail.com>
10 
11    Copyright 2016, 2017 Google Inc. All rights reserved.
12    Copyright 2019-2020 AFLplusplus Project. All rights reserved.
13 
14    Licensed under the Apache License, Version 2.0 (the "License");
15    you may not use this file except in compliance with the License.
16    You may obtain a copy of the License at:
17 
18      http://www.apache.org/licenses/LICENSE-2.0
19 
20    This is the real deal: the program takes an instrumented binary and
21    attempts a variety of basic fuzzing tricks, paying close attention to
22    how they affect the execution path.
23 
24  */
25 
26 #include "afl-fuzz.h"
27 #include "cmplog.h"
28 #include <limits.h>
29 #include <stdlib.h>
30 #ifndef USEMMAP
31   #include <sys/mman.h>
32   #include <sys/stat.h>
33   #include <fcntl.h>
34   #include <sys/ipc.h>
35   #include <sys/shm.h>
36 #endif
37 
38 #ifdef __APPLE__
39   #include <sys/qos.h>
40 #endif
41 
42 #ifdef PROFILING
43 extern u64 time_spent_working;
44 #endif
45 
at_exit()46 static void at_exit() {
47 
48   s32   i, pid1 = 0, pid2 = 0;
49   char *list[4] = {SHM_ENV_VAR, SHM_FUZZ_ENV_VAR, CMPLOG_SHM_ENV_VAR, NULL};
50   char *ptr;
51 
52   ptr = getenv(CPU_AFFINITY_ENV_VAR);
53   if (ptr && *ptr) unlink(ptr);
54 
55   ptr = getenv("__AFL_TARGET_PID1");
56   if (ptr && *ptr && (pid1 = atoi(ptr)) > 0) kill(pid1, SIGTERM);
57 
58   ptr = getenv("__AFL_TARGET_PID2");
59   if (ptr && *ptr && (pid2 = atoi(ptr)) > 0) kill(pid2, SIGTERM);
60 
61   i = 0;
62   while (list[i] != NULL) {
63 
64     ptr = getenv(list[i]);
65     if (ptr && *ptr) {
66 
67 #ifdef USEMMAP
68 
69       shm_unlink(ptr);
70 
71 #else
72 
73       shmctl(atoi(ptr), IPC_RMID, NULL);
74 
75 #endif
76 
77     }
78 
79     i++;
80 
81   }
82 
83   int kill_signal = SIGKILL;
84   /* AFL_KILL_SIGNAL should already be a valid int at this point */
85   if ((ptr = getenv("AFL_KILL_SIGNAL"))) { kill_signal = atoi(ptr); }
86 
87   if (pid1 > 0) { kill(pid1, kill_signal); }
88   if (pid2 > 0) { kill(pid2, kill_signal); }
89 
90 }
91 
92 /* Display usage hints. */
93 
usage(u8 * argv0,int more_help)94 static void usage(u8 *argv0, int more_help) {
95 
96   SAYF(
97       "\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
98 
99       "Required parameters:\n"
100       "  -i dir        - input directory with test cases\n"
101       "  -o dir        - output directory for fuzzer findings\n\n"
102 
103       "Execution control settings:\n"
104       "  -p schedule   - power schedules compute a seed's performance score:\n"
105       "                  fast(default), explore, exploit, seek, rare, mmopt, "
106       "coe, lin\n"
107       "                  quad -- see docs/power_schedules.md\n"
108       "  -f file       - location read by the fuzzed program (default: stdin "
109       "or @@)\n"
110       "  -t msec       - timeout for each run (auto-scaled, default %u ms). "
111       "Add a '+'\n"
112       "                  to auto-calculate the timeout, the value being the "
113       "maximum.\n"
114       "  -m megs       - memory limit for child process (%u MB, 0 = no limit "
115       "[default])\n"
116       "  -O            - use binary-only instrumentation (FRIDA mode)\n"
117       "  -Q            - use binary-only instrumentation (QEMU mode)\n"
118       "  -U            - use unicorn-based instrumentation (Unicorn mode)\n"
119       "  -W            - use qemu-based instrumentation with Wine (Wine "
120       "mode)\n\n"
121 
122       "Mutator settings:\n"
123       "  -D            - enable deterministic fuzzing (once per queue entry)\n"
124       "  -L minutes    - use MOpt(imize) mode and set the time limit for "
125       "entering the\n"
126       "                  pacemaker mode (minutes of no new paths). 0 = "
127       "immediately,\n"
128       "                  -1 = immediately and together with normal mutation.\n"
129       "                  See docs/README.MOpt.md\n"
130       "  -c program    - enable CmpLog by specifying a binary compiled for "
131       "it.\n"
132       "                  if using QEMU, just use -c 0.\n"
133       "  -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n"
134       "                  1=small files, 2=larger files (default), 3=all "
135       "files,\n"
136       "                  A=arithmetic solving, T=transformational solving.\n\n"
137       "Fuzzing behavior settings:\n"
138       "  -Z            - sequential queue selection instead of weighted "
139       "random\n"
140       "  -N            - do not unlink the fuzzing input file (for devices "
141       "etc.)\n"
142       "  -n            - fuzz without instrumentation (non-instrumented mode)\n"
143       "  -x dict_file  - fuzzer dictionary (see README.md, specify up to 4 "
144       "times)\n\n"
145 
146       "Test settings:\n"
147       "  -s seed       - use a fixed seed for the RNG\n"
148       "  -V seconds    - fuzz for a specified time then terminate\n"
149       "  -E execs      - fuzz for an approx. no. of total executions then "
150       "terminate\n"
151       "                  Note: not precise and can have several more "
152       "executions.\n\n"
153 
154       "Other stuff:\n"
155       "  -M/-S id      - distributed mode (see docs/parallel_fuzzing.md)\n"
156       "                  -M auto-sets -D, -Z (use -d to disable -D) and no "
157       "trimming\n"
158       "  -F path       - sync to a foreign fuzzer queue directory (requires "
159       "-M, can\n"
160       "                  be specified up to %u times)\n"
161       // "  -d            - skip deterministic fuzzing in -M mode\n"
162       "  -T text       - text banner to show on the screen\n"
163       "  -I command    - execute this command/script when a new crash is "
164       "found\n"
165       //"  -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
166       //" "file\n"
167       "  -C            - crash exploration mode (the peruvian rabbit thing)\n"
168       "  -b cpu_id     - bind the fuzzing process to the specified CPU core "
169       "(0-...)\n"
170       "  -e ext        - file extension for the fuzz test input file (if "
171       "needed)\n\n",
172       argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX);
173 
174   if (more_help > 1) {
175 
176 #if defined USE_COLOR && !defined ALWAYS_COLORED
177   #define DYN_COLOR \
178     "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off\n"
179 #else
180   #define DYN_COLOR
181 #endif
182 
183 #ifdef AFL_PERSISTENT_RECORD
184   #define PERSISTENT_MSG                                                 \
185     "AFL_PERSISTENT_RECORD: record the last X inputs to every crash in " \
186     "out/crashes\n"
187 #else
188   #define PERSISTENT_MSG
189 #endif
190 
191     SAYF(
192       "Environment variables used:\n"
193       "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
194       "ASAN_OPTIONS: custom settings for ASAN\n"
195       "              (must contain abort_on_error=1 and symbolize=0)\n"
196       "MSAN_OPTIONS: custom settings for MSAN\n"
197       "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
198       "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n"
199       "AFL_BENCH_JUST_ONE: run the target just once\n"
200       "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n"
201       "AFL_CMPLOG_ONLY_NEW: do not run cmplog on initial testcases (good for resumes!)\n"
202       "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n"
203       "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n"
204       "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n"
205       "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule\n"
206       "AFL_DEBUG: extra debugging output for Python mode trimming\n"
207       "AFL_DEBUG_CHILD: do not suppress stdout/stderr from target\n"
208       "AFL_DISABLE_TRIM: disable the trimming of test cases\n"
209       "AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
210       "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
211       "AFL_EXIT_ON_TIME: exit when no new paths are found within the specified time period\n"
212       "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n"
213       "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
214       "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
215       "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
216       "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
217       "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
218       "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
219       "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
220       "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
221       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
222       "              the target was compiled for\n"
223       "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
224       "                    then they are randomly selected instead all of them being\n"
225       "                    used. Defaults to 200.\n"
226       "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
227       "AFL_TRY_AFFINITY: try to bind to an unused core, but don't fail if unsuccessful\n"
228       "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
229       "AFL_NO_AUTODICT: do not load an offered auto dictionary compiled into a target\n"
230       "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
231       "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
232       "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
233       "AFL_NO_UI: switch status screen off\n"
234 
235       DYN_COLOR
236 
237       "AFL_PATH: path to AFL support binaries\n"
238       "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
239       "AFL_QUIET: suppress forkserver status messages\n"
240 
241       PERSISTENT_MSG
242 
243       "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
244       "AFL_TARGET_ENV: pass extra environment variables to target\n"
245       "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
246       "AFL_SKIP_BIN_CHECK: skip afl compatibility checks, also disables auto map size\n"
247       "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
248       //"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
249       "AFL_STATSD: enables StatsD metrics collection\n"
250       "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n"
251       "AFL_STATSD_PORT: change default statsd port (default: 8125)\n"
252       "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n"
253       "                        Supported formats are: 'dogstatsd', 'librato',\n"
254       "                        'signalfx' and 'influxdb'\n"
255       "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n"
256       "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
257       //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n"
258       //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n"
259       "\n"
260     );
261 
262   } else {
263 
264     SAYF(
265         "To view also the supported environment variables of afl-fuzz please "
266         "use \"-hh\".\n\n");
267 
268   }
269 
270 #ifdef USE_PYTHON
271   SAYF("Compiled with %s module support, see docs/custom_mutator.md\n",
272        (char *)PYTHON_VERSION);
273 #else
274   SAYF("Compiled without python module support.\n");
275 #endif
276 
277 #ifdef AFL_PERSISTENT_RECORD
278   SAYF("Compiled with AFL_PERSISTENT_RECORD support.\n");
279 #else
280   SAYF("Compiled without AFL_PERSISTENT_RECORD support.\n");
281 #endif
282 
283 #ifdef USEMMAP
284   SAYF("Compiled with shm_open support.\n");
285 #else
286   SAYF("Compiled with shmat support.\n");
287 #endif
288 
289 #ifdef ASAN_BUILD
290   SAYF("Compiled with ASAN_BUILD.\n");
291 #endif
292 
293 #ifdef NO_SPLICING
294   SAYF("Compiled with NO_SPLICING.\n");
295 #endif
296 
297 #ifdef PROFILING
298   SAYF("Compiled with PROFILING.\n");
299 #endif
300 
301 #ifdef INTROSPECTION
302   SAYF("Compiled with INTROSPECTION.\n");
303 #endif
304 
305 #ifdef _DEBUG
306   SAYF("Compiled with _DEBUG.\n");
307 #endif
308 
309 #ifdef _AFL_DOCUMENT_MUTATIONS
310   SAYF("Compiled with _AFL_DOCUMENT_MUTATIONS.\n");
311 #endif
312 
313   SAYF("For additional help please consult %s/README.md :)\n\n", doc_path);
314 
315   exit(1);
316 #undef PHYTON_SUPPORT
317 
318 }
319 
320 #ifndef AFL_LIB
321 
stricmp(char const * a,char const * b)322 static int stricmp(char const *a, char const *b) {
323 
324   if (!a || !b) { FATAL("Null reference"); }
325 
326   for (;; ++a, ++b) {
327 
328     int d;
329     d = tolower((int)*a) - tolower((int)*b);
330     if (d != 0 || !*a) { return d; }
331 
332   }
333 
334 }
335 
fasan_check_afl_preload(char * afl_preload)336 static void fasan_check_afl_preload(char *afl_preload) {
337 
338   char   first_preload[PATH_MAX + 1] = {0};
339   char * separator = strchr(afl_preload, ':');
340   size_t first_preload_len = PATH_MAX;
341   char * basename;
342   char   clang_runtime_prefix[] = "libclang_rt.asan-";
343 
344   if (separator != NULL && (separator - afl_preload) < PATH_MAX) {
345 
346     first_preload_len = separator - afl_preload;
347 
348   }
349 
350   strncpy(first_preload, afl_preload, first_preload_len);
351 
352   basename = strrchr(first_preload, '/');
353   if (basename == NULL) {
354 
355     basename = first_preload;
356 
357   } else {
358 
359     basename = basename + 1;
360 
361   }
362 
363   if (strncmp(basename, clang_runtime_prefix,
364               sizeof(clang_runtime_prefix) - 1) != 0) {
365 
366     FATAL("Address Sanitizer DSO must be the first DSO in AFL_PRELOAD");
367 
368   }
369 
370   if (access(first_preload, R_OK) != 0) {
371 
372     FATAL("Address Sanitizer DSO not found");
373 
374   }
375 
376   OKF("Found ASAN DSO: %s", first_preload);
377 
378 }
379 
380 /* Main entry point */
381 
main(int argc,char ** argv_orig,char ** envp)382 int main(int argc, char **argv_orig, char **envp) {
383 
384   s32 opt, auto_sync = 0 /*, user_set_cache = 0*/;
385   u64 prev_queued = 0;
386   u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0,
387       map_size = get_map_size();
388   u8 *extras_dir[4];
389   u8  mem_limit_given = 0, exit_1 = 0, debug = 0,
390      extras_dir_cnt = 0 /*, have_p = 0*/;
391   char * afl_preload;
392   char * frida_afl_preload = NULL;
393   char **use_argv;
394 
395   struct timeval  tv;
396   struct timezone tz;
397 
398   #if defined USE_COLOR && defined ALWAYS_COLORED
399   if (getenv("AFL_NO_COLOR") || getenv("AFL_NO_COLOUR")) {
400 
401     WARNF(
402         "Setting AFL_NO_COLOR has no effect (colors are configured on at "
403         "compile time)");
404 
405   }
406 
407   #endif
408 
409   char **argv = argv_cpy_dup(argc, argv_orig);
410 
411   afl_state_t *afl = calloc(1, sizeof(afl_state_t));
412   if (!afl) { FATAL("Could not create afl state"); }
413 
414   if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; }
415 
416   afl_state_init(afl, map_size);
417   afl->debug = debug;
418   afl_fsrv_init(&afl->fsrv);
419   if (debug) { afl->fsrv.debug = true; }
420   read_afl_environment(afl, envp);
421   if (afl->shm.map_size) { afl->fsrv.map_size = afl->shm.map_size; }
422   exit_1 = !!afl->afl_env.afl_bench_just_one;
423 
424   SAYF(cCYA "afl-fuzz" VERSION cRST
425             " based on afl by Michal Zalewski and a large online community\n");
426 
427   doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
428 
429   gettimeofday(&tv, &tz);
430   rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
431 
432   afl->shmem_testcase_mode = 1;  // we always try to perform shmem fuzzing
433 
434   while ((opt = getopt(
435               argc, argv,
436               "+b:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) > 0) {
437 
438     switch (opt) {
439 
440       case 'Z':
441         afl->old_seed_selection = 1;
442         break;
443 
444       case 'I':
445         afl->infoexec = optarg;
446         break;
447 
448       case 'b': {                                          /* bind CPU core */
449 
450         if (afl->cpu_to_bind != -1) FATAL("Multiple -b options not supported");
451 
452         if (sscanf(optarg, "%d", &afl->cpu_to_bind) < 0) {
453 
454           FATAL("Bad syntax used for -b");
455 
456         }
457 
458         break;
459 
460       }
461 
462       case 'c': {
463 
464         afl->shm.cmplog_mode = 1;
465         afl->cmplog_binary = ck_strdup(optarg);
466         break;
467 
468       }
469 
470       case 's': {
471 
472         if (optarg == NULL) { FATAL("No valid seed provided. Got NULL."); }
473         rand_set_seed(afl, strtoul(optarg, 0L, 10));
474         afl->fixed_seed = 1;
475         break;
476 
477       }
478 
479       case 'p':                                           /* Power schedule */
480 
481         if (!stricmp(optarg, "fast")) {
482 
483           afl->schedule = FAST;
484 
485         } else if (!stricmp(optarg, "coe")) {
486 
487           afl->schedule = COE;
488 
489         } else if (!stricmp(optarg, "exploit")) {
490 
491           afl->schedule = EXPLOIT;
492 
493         } else if (!stricmp(optarg, "lin")) {
494 
495           afl->schedule = LIN;
496 
497         } else if (!stricmp(optarg, "quad")) {
498 
499           afl->schedule = QUAD;
500 
501         } else if (!stricmp(optarg, "mopt") || !stricmp(optarg, "mmopt")) {
502 
503           afl->schedule = MMOPT;
504 
505         } else if (!stricmp(optarg, "rare")) {
506 
507           afl->schedule = RARE;
508 
509         } else if (!stricmp(optarg, "explore") || !stricmp(optarg, "afl") ||
510 
511                    !stricmp(optarg, "default") ||
512 
513                    !stricmp(optarg, "normal")) {
514 
515           afl->schedule = EXPLORE;
516 
517         } else if (!stricmp(optarg, "seek")) {
518 
519           afl->schedule = SEEK;
520 
521         } else {
522 
523           FATAL("Unknown -p power schedule");
524 
525         }
526 
527         // have_p = 1;
528 
529         break;
530 
531       case 'e':
532 
533         if (afl->file_extension) { FATAL("Multiple -e options not supported"); }
534 
535         afl->file_extension = optarg;
536 
537         break;
538 
539       case 'i':                                                /* input dir */
540 
541         if (afl->in_dir) { FATAL("Multiple -i options not supported"); }
542         if (optarg == NULL) { FATAL("Invalid -i option (got NULL)."); }
543         afl->in_dir = optarg;
544 
545         if (!strcmp(afl->in_dir, "-")) { afl->in_place_resume = 1; }
546 
547         break;
548 
549       case 'o':                                               /* output dir */
550 
551         if (afl->out_dir) { FATAL("Multiple -o options not supported"); }
552         afl->out_dir = optarg;
553         break;
554 
555       case 'M': {                                           /* main sync ID */
556 
557         u8 *c;
558 
559         if (afl->non_instrumented_mode) {
560 
561           FATAL("-M is not supported in non-instrumented mode");
562 
563         }
564 
565         if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
566 
567         /* sanity check for argument: should not begin with '-' (possible
568          * option) */
569         if (optarg && *optarg == '-') {
570 
571           FATAL(
572               "argument for -M started with a dash '-', which is used for "
573               "options");
574 
575         }
576 
577         afl->sync_id = ck_strdup(optarg);
578         afl->old_seed_selection = 1;  // force old queue walking seed selection
579         afl->disable_trim = 1;        // disable trimming
580 
581         if ((c = strchr(afl->sync_id, ':'))) {
582 
583           *c = 0;
584 
585           if (sscanf(c + 1, "%u/%u", &afl->main_node_id, &afl->main_node_max) !=
586                   2 ||
587               !afl->main_node_id || !afl->main_node_max ||
588               afl->main_node_id > afl->main_node_max ||
589               afl->main_node_max > 1000000) {
590 
591             FATAL("Bogus main node ID passed to -M");
592 
593           }
594 
595         }
596 
597         afl->is_main_node = 1;
598 
599       }
600 
601       break;
602 
603       case 'S':                                        /* secondary sync id */
604 
605         if (afl->non_instrumented_mode) {
606 
607           FATAL("-S is not supported in non-instrumented mode");
608 
609         }
610 
611         if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
612 
613         /* sanity check for argument: should not begin with '-' (possible
614          * option) */
615         if (optarg && *optarg == '-') {
616 
617           FATAL(
618               "argument for -M started with a dash '-', which is used for "
619               "options");
620 
621         }
622 
623         afl->sync_id = ck_strdup(optarg);
624         afl->is_secondary_node = 1;
625         break;
626 
627       case 'F':                                         /* foreign sync dir */
628 
629         if (!optarg) { FATAL("Missing path for -F"); }
630         if (!afl->is_main_node) {
631 
632           FATAL(
633               "Option -F can only be specified after the -M option for the "
634               "main fuzzer of a fuzzing campaign");
635 
636         }
637 
638         if (afl->foreign_sync_cnt >= FOREIGN_SYNCS_MAX) {
639 
640           FATAL("Maximum %u entried of -F option can be specified",
641                 FOREIGN_SYNCS_MAX);
642 
643         }
644 
645         afl->foreign_syncs[afl->foreign_sync_cnt].dir = optarg;
646         while (afl->foreign_syncs[afl->foreign_sync_cnt]
647                    .dir[strlen(afl->foreign_syncs[afl->foreign_sync_cnt].dir) -
648                         1] == '/') {
649 
650           afl->foreign_syncs[afl->foreign_sync_cnt]
651               .dir[strlen(afl->foreign_syncs[afl->foreign_sync_cnt].dir) - 1] =
652               0;
653 
654         }
655 
656         afl->foreign_sync_cnt++;
657         break;
658 
659       case 'f':                                              /* target file */
660 
661         if (afl->fsrv.out_file) { FATAL("Multiple -f options not supported"); }
662         afl->fsrv.out_file = ck_strdup(optarg);
663         afl->fsrv.use_stdin = 0;
664         break;
665 
666       case 'x':                                               /* dictionary */
667 
668         if (extras_dir_cnt >= 4) {
669 
670           FATAL("More than four -x options are not supported");
671 
672         }
673 
674         extras_dir[extras_dir_cnt++] = optarg;
675         break;
676 
677       case 't': {                                                /* timeout */
678 
679         u8 suffix = 0;
680 
681         if (afl->timeout_given) { FATAL("Multiple -t options not supported"); }
682 
683         if (!optarg ||
684             sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 ||
685             optarg[0] == '-') {
686 
687           FATAL("Bad syntax used for -t");
688 
689         }
690 
691         if (afl->fsrv.exec_tmout < 5) { FATAL("Dangerously low value of -t"); }
692 
693         if (suffix == '+') {
694 
695           afl->timeout_given = 2;
696 
697         } else {
698 
699           afl->timeout_given = 1;
700 
701         }
702 
703         break;
704 
705       }
706 
707       case 'm': {                                              /* mem limit */
708 
709         u8 suffix = 'M';
710 
711         if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
712         mem_limit_given = 1;
713 
714         if (!optarg) { FATAL("Wrong usage of -m"); }
715 
716         if (!strcmp(optarg, "none")) {
717 
718           afl->fsrv.mem_limit = 0;
719           break;
720 
721         }
722 
723         if (sscanf(optarg, "%llu%c", &afl->fsrv.mem_limit, &suffix) < 1 ||
724             optarg[0] == '-') {
725 
726           FATAL("Bad syntax used for -m");
727 
728         }
729 
730         switch (suffix) {
731 
732           case 'T':
733             afl->fsrv.mem_limit *= 1024 * 1024;
734             break;
735           case 'G':
736             afl->fsrv.mem_limit *= 1024;
737             break;
738           case 'k':
739             afl->fsrv.mem_limit /= 1024;
740             break;
741           case 'M':
742             break;
743 
744           default:
745             FATAL("Unsupported suffix or bad syntax for -m");
746 
747         }
748 
749         if (afl->fsrv.mem_limit < 5) { FATAL("Dangerously low value of -m"); }
750 
751         if (sizeof(rlim_t) == 4 && afl->fsrv.mem_limit > 2000) {
752 
753           FATAL("Value of -m out of range on 32-bit systems");
754 
755         }
756 
757       }
758 
759       break;
760 
761       case 'D':                                    /* enforce deterministic */
762 
763         afl->skip_deterministic = 0;
764         break;
765 
766       case 'd':                                       /* skip deterministic */
767 
768         afl->skip_deterministic = 1;
769         break;
770 
771       case 'B':                                              /* load bitmap */
772 
773         /* This is a secret undocumented option! It is useful if you find
774            an interesting test case during a normal fuzzing process, and want
775            to mutate it without rediscovering any of the test cases already
776            found during an earlier run.
777 
778            To use this mode, you need to point -B to the fuzz_bitmap produced
779            by an earlier run for the exact same binary... and that's it.
780 
781            I only used this once or twice to get variants of a particular
782            file, so I'm not making this an official setting. */
783 
784         if (afl->in_bitmap) { FATAL("Multiple -B options not supported"); }
785 
786         afl->in_bitmap = optarg;
787         break;
788 
789       case 'C':                                               /* crash mode */
790 
791         if (afl->crash_mode) { FATAL("Multiple -C options not supported"); }
792         afl->crash_mode = FSRV_RUN_CRASH;
793         break;
794 
795       case 'n':                                                /* dumb mode */
796 
797         if (afl->is_main_node || afl->is_secondary_node) {
798 
799           FATAL("Non instrumented mode is not supported with -M / -S");
800 
801         }
802 
803         if (afl->non_instrumented_mode) {
804 
805           FATAL("Multiple -n options not supported");
806 
807         }
808 
809         if (afl->afl_env.afl_dumb_forksrv) {
810 
811           afl->non_instrumented_mode = 2;
812 
813         } else {
814 
815           afl->non_instrumented_mode = 1;
816 
817         }
818 
819         break;
820 
821       case 'T':                                                   /* banner */
822 
823         if (afl->use_banner) { FATAL("Multiple -T options not supported"); }
824         afl->use_banner = optarg;
825         break;
826 
827       case 'O':                                               /* FRIDA mode */
828 
829         if (afl->fsrv.frida_mode) {
830 
831           FATAL("Multiple -O options not supported");
832 
833         }
834 
835         afl->fsrv.frida_mode = 1;
836         if (get_afl_env("AFL_USE_FASAN")) { afl->fsrv.frida_asan = 1; }
837 
838         break;
839 
840       case 'Q':                                                /* QEMU mode */
841 
842         if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); }
843         afl->fsrv.qemu_mode = 1;
844 
845         if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
846 
847         break;
848 
849       case 'N':                                             /* Unicorn mode */
850 
851         if (afl->no_unlink) { FATAL("Multiple -N options not supported"); }
852         afl->fsrv.no_unlink = (afl->no_unlink = true);
853 
854         break;
855 
856       case 'U':                                             /* Unicorn mode */
857 
858         if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); }
859         afl->unicorn_mode = 1;
860 
861         if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; }
862 
863         break;
864 
865       case 'W':                                           /* Wine+QEMU mode */
866 
867         if (afl->use_wine) { FATAL("Multiple -W options not supported"); }
868         afl->fsrv.qemu_mode = 1;
869         afl->use_wine = 1;
870 
871         if (!mem_limit_given) { afl->fsrv.mem_limit = 0; }
872 
873         break;
874 
875       case 'V': {
876 
877         afl->most_time_key = 1;
878         if (!optarg || sscanf(optarg, "%llu", &afl->most_time) < 1 ||
879             optarg[0] == '-') {
880 
881           FATAL("Bad syntax used for -V");
882 
883         }
884 
885       } break;
886 
887       case 'E': {
888 
889         afl->most_execs_key = 1;
890         if (!optarg || sscanf(optarg, "%llu", &afl->most_execs) < 1 ||
891             optarg[0] == '-') {
892 
893           FATAL("Bad syntax used for -E");
894 
895         }
896 
897       } break;
898 
899       case 'l': {
900 
901         if (!optarg) { FATAL("missing parameter for 'l'"); }
902         char *c = optarg;
903         while (*c) {
904 
905           switch (*c) {
906 
907             case '0':
908             case '1':
909               afl->cmplog_lvl = 1;
910               break;
911             case '2':
912               afl->cmplog_lvl = 2;
913               break;
914             case '3':
915               afl->cmplog_lvl = 3;
916 
917               if (!afl->disable_trim) {
918 
919                 ACTF("Deactivating trimming due CMPLOG level 3");
920                 afl->disable_trim = 1;
921 
922               }
923 
924               break;
925             case 'a':
926             case 'A':
927               afl->cmplog_enable_arith = 1;
928               break;
929             case 't':
930             case 'T':
931               afl->cmplog_enable_transform = 1;
932               break;
933             default:
934               FATAL("Unknown option value '%c' in -l %s", *c, optarg);
935 
936           }
937 
938           ++c;
939 
940         }
941 
942         if (afl->cmplog_lvl == CMPLOG_LVL_MAX) {
943 
944           afl->cmplog_max_filesize = MAX_FILE;
945 
946         }
947 
948       } break;
949 
950       case 'L': {                                              /* MOpt mode */
951 
952         if (afl->limit_time_sig) { FATAL("Multiple -L options not supported"); }
953         afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
954 
955         if (sscanf(optarg, "%d", &afl->limit_time_puppet) < 1) {
956 
957           FATAL("Bad syntax used for -L");
958 
959         }
960 
961         if (afl->limit_time_puppet == -1) {
962 
963           afl->limit_time_sig = -1;
964           afl->limit_time_puppet = 0;
965 
966         } else if (afl->limit_time_puppet < 0) {
967 
968           FATAL("-L value must be between 0 and 2000000 or -1");
969 
970         } else {
971 
972           afl->limit_time_sig = 1;
973 
974         }
975 
976         u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000;
977 
978         if ((s32)limit_time_puppet2 < afl->limit_time_puppet) {
979 
980           FATAL("limit_time overflow");
981 
982         }
983 
984         afl->limit_time_puppet = limit_time_puppet2;
985         afl->swarm_now = 0;
986         if (afl->limit_time_puppet == 0) { afl->key_puppet = 1; }
987 
988         int j;
989         int tmp_swarm = 0;
990 
991         if (afl->g_now > afl->g_max) { afl->g_now = 0; }
992         afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) /
993                          (afl->g_max) +
994                      afl->w_end;
995 
996         for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) {
997 
998           double total_puppet_temp = 0.0;
999           afl->swarm_fitness[tmp_swarm] = 0.0;
1000 
1001           for (j = 0; j < operator_num; ++j) {
1002 
1003             afl->stage_finds_puppet[tmp_swarm][j] = 0;
1004             afl->probability_now[tmp_swarm][j] = 0.0;
1005             afl->x_now[tmp_swarm][j] =
1006                 ((double)(random() % 7000) * 0.0001 + 0.1);
1007             total_puppet_temp += afl->x_now[tmp_swarm][j];
1008             afl->v_now[tmp_swarm][j] = 0.1;
1009             afl->L_best[tmp_swarm][j] = 0.5;
1010             afl->G_best[j] = 0.5;
1011             afl->eff_best[tmp_swarm][j] = 0.0;
1012 
1013           }
1014 
1015           for (j = 0; j < operator_num; ++j) {
1016 
1017             afl->stage_cycles_puppet_v2[tmp_swarm][j] =
1018                 afl->stage_cycles_puppet[tmp_swarm][j];
1019             afl->stage_finds_puppet_v2[tmp_swarm][j] =
1020                 afl->stage_finds_puppet[tmp_swarm][j];
1021             afl->x_now[tmp_swarm][j] =
1022                 afl->x_now[tmp_swarm][j] / total_puppet_temp;
1023 
1024           }
1025 
1026           double x_temp = 0.0;
1027 
1028           for (j = 0; j < operator_num; ++j) {
1029 
1030             afl->probability_now[tmp_swarm][j] = 0.0;
1031             afl->v_now[tmp_swarm][j] =
1032                 afl->w_now * afl->v_now[tmp_swarm][j] +
1033                 RAND_C *
1034                     (afl->L_best[tmp_swarm][j] - afl->x_now[tmp_swarm][j]) +
1035                 RAND_C * (afl->G_best[j] - afl->x_now[tmp_swarm][j]);
1036 
1037             afl->x_now[tmp_swarm][j] += afl->v_now[tmp_swarm][j];
1038 
1039             if (afl->x_now[tmp_swarm][j] > v_max) {
1040 
1041               afl->x_now[tmp_swarm][j] = v_max;
1042 
1043             } else if (afl->x_now[tmp_swarm][j] < v_min) {
1044 
1045               afl->x_now[tmp_swarm][j] = v_min;
1046 
1047             }
1048 
1049             x_temp += afl->x_now[tmp_swarm][j];
1050 
1051           }
1052 
1053           for (j = 0; j < operator_num; ++j) {
1054 
1055             afl->x_now[tmp_swarm][j] = afl->x_now[tmp_swarm][j] / x_temp;
1056             if (likely(j != 0)) {
1057 
1058               afl->probability_now[tmp_swarm][j] =
1059                   afl->probability_now[tmp_swarm][j - 1] +
1060                   afl->x_now[tmp_swarm][j];
1061 
1062             } else {
1063 
1064               afl->probability_now[tmp_swarm][j] = afl->x_now[tmp_swarm][j];
1065 
1066             }
1067 
1068           }
1069 
1070           if (afl->probability_now[tmp_swarm][operator_num - 1] < 0.99 ||
1071               afl->probability_now[tmp_swarm][operator_num - 1] > 1.01) {
1072 
1073             FATAL("ERROR probability");
1074 
1075           }
1076 
1077         }
1078 
1079         for (j = 0; j < operator_num; ++j) {
1080 
1081           afl->core_operator_finds_puppet[j] = 0;
1082           afl->core_operator_finds_puppet_v2[j] = 0;
1083           afl->core_operator_cycles_puppet[j] = 0;
1084           afl->core_operator_cycles_puppet_v2[j] = 0;
1085           afl->core_operator_cycles_puppet_v3[j] = 0;
1086 
1087         }
1088 
1089       } break;
1090 
1091       case 'h':
1092         show_help++;
1093         break;  // not needed
1094 
1095       case 'R':
1096 
1097         FATAL(
1098             "Radamsa is now a custom mutator, please use that "
1099             "(custom_mutators/radamsa/).");
1100 
1101         break;
1102 
1103       default:
1104         if (!show_help) { show_help = 1; }
1105 
1106     }
1107 
1108   }
1109 
1110   if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) {
1111 
1112     usage(argv[0], show_help);
1113 
1114   }
1115 
1116   if (unlikely(afl->afl_env.afl_persistent_record)) {
1117 
1118   #ifdef AFL_PERSISTENT_RECORD
1119 
1120     afl->fsrv.persistent_record = atoi(afl->afl_env.afl_persistent_record);
1121 
1122     if (afl->fsrv.persistent_record < 2) {
1123 
1124       FATAL(
1125           "AFL_PERSISTENT_RECORD value must be be at least 2, recommended is "
1126           "100 or 1000.");
1127 
1128     }
1129 
1130   #else
1131 
1132     FATAL(
1133         "afl-fuzz was not compiled with AFL_PERSISTENT_RECORD enabled in "
1134         "config.h!");
1135 
1136   #endif
1137 
1138   }
1139 
1140   if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
1141 
1142   OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
1143       "Eißfeldt, Andrea Fioraldi and Dominik Maier");
1144   OKF("afl++ is open source, get it at "
1145       "https://github.com/AFLplusplus/AFLplusplus");
1146   OKF("NOTE: This is v3.x which changes defaults and behaviours - see "
1147       "README.md");
1148 
1149   if (afl->sync_id && afl->is_main_node &&
1150       afl->afl_env.afl_custom_mutator_only) {
1151 
1152     WARNF(
1153         "Using -M main node with the AFL_CUSTOM_MUTATOR_ONLY mutator options "
1154         "will result in no deterministic mutations being done!");
1155 
1156   }
1157 
1158   if (afl->fixed_seed) {
1159 
1160     OKF("Running with fixed seed: %u", (u32)afl->init_seed);
1161 
1162   }
1163 
1164   #if defined(__SANITIZE_ADDRESS__)
1165   if (afl->fsrv.mem_limit) {
1166 
1167     WARNF("in the ASAN build we disable all memory limits");
1168     afl->fsrv.mem_limit = 0;
1169 
1170   }
1171 
1172   #endif
1173 
1174   afl->fsrv.kill_signal =
1175       parse_afl_kill_signal_env(afl->afl_env.afl_kill_signal, SIGKILL);
1176 
1177   setup_signal_handlers();
1178   check_asan_opts(afl);
1179 
1180   afl->power_name = power_names[afl->schedule];
1181 
1182   if (!afl->non_instrumented_mode && !afl->sync_id) {
1183 
1184     auto_sync = 1;
1185     afl->sync_id = ck_strdup("default");
1186     afl->is_secondary_node = 1;
1187     OKF("No -M/-S set, autoconfiguring for \"-S %s\"", afl->sync_id);
1188 
1189   }
1190 
1191   if (afl->sync_id) { fix_up_sync(afl); }
1192 
1193   if (!strcmp(afl->in_dir, afl->out_dir)) {
1194 
1195     FATAL("Input and output directories can't be the same");
1196 
1197   }
1198 
1199   if (afl->non_instrumented_mode) {
1200 
1201     if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
1202     if (afl->fsrv.frida_mode) { FATAL("-O and -n are mutually exclusive"); }
1203     if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
1204     if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); }
1205 
1206   }
1207 
1208   setenv("__AFL_OUT_DIR", afl->out_dir, 1);
1209 
1210   if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; }
1211 
1212   if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) {
1213 
1214     FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive");
1215 
1216   }
1217 
1218   if (unlikely(afl->afl_env.afl_statsd)) { statsd_setup_format(afl); }
1219 
1220   if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) {
1221 
1222     WARNF(cLRD
1223           "Target binary called without a prefixed path, make sure you are "
1224           "fuzzing the right binary: " cRST "%s",
1225           argv[optind]);
1226 
1227   }
1228 
1229   ACTF("Getting to work...");
1230 
1231   switch (afl->schedule) {
1232 
1233     case FAST:
1234       OKF("Using exponential power schedule (FAST)");
1235       break;
1236     case COE:
1237       OKF("Using cut-off exponential power schedule (COE)");
1238       break;
1239     case EXPLOIT:
1240       OKF("Using exploitation-based constant power schedule (EXPLOIT)");
1241       break;
1242     case LIN:
1243       OKF("Using linear power schedule (LIN)");
1244       break;
1245     case QUAD:
1246       OKF("Using quadratic power schedule (QUAD)");
1247       break;
1248     case MMOPT:
1249       OKF("Using modified MOpt power schedule (MMOPT)");
1250       break;
1251     case RARE:
1252       OKF("Using rare edge focus power schedule (RARE)");
1253       break;
1254     case SEEK:
1255       OKF("Using seek power schedule (SEEK)");
1256       break;
1257     case EXPLORE:
1258       OKF("Using exploration-based constant power schedule (EXPLORE)");
1259       break;
1260     default:
1261       FATAL("Unknown power schedule");
1262       break;
1263 
1264   }
1265 
1266   if (afl->shm.cmplog_mode) { OKF("CmpLog level: %u", afl->cmplog_lvl); }
1267 
1268   /* Dynamically allocate memory for AFLFast schedules */
1269   if (afl->schedule >= FAST && afl->schedule <= RARE) {
1270 
1271     afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32));
1272 
1273   }
1274 
1275   if (get_afl_env("AFL_NO_FORKSRV")) { afl->no_forkserver = 1; }
1276   if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; }
1277   if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
1278   if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
1279   if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
1280 
1281   if (afl->afl_env.afl_autoresume) {
1282 
1283     afl->autoresume = 1;
1284     if (afl->in_place_resume) {
1285 
1286       SAYF("AFL_AUTORESUME has no effect for '-i -'");
1287 
1288     }
1289 
1290   }
1291 
1292   if (afl->afl_env.afl_hang_tmout) {
1293 
1294     s32 hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
1295     if (hang_tmout < 1) { FATAL("Invalid value for AFL_HANG_TMOUT"); }
1296     afl->hang_tmout = (u32)hang_tmout;
1297 
1298   }
1299 
1300   if (afl->afl_env.afl_exit_on_time) {
1301 
1302     u64 exit_on_time = atoi(afl->afl_env.afl_exit_on_time);
1303     afl->exit_on_time = (u64)exit_on_time * 1000;
1304 
1305   }
1306 
1307   if (afl->afl_env.afl_max_det_extras) {
1308 
1309     s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
1310     if (max_det_extras < 1) { FATAL("Invalid value for AFL_MAX_DET_EXTRAS"); }
1311     afl->max_det_extras = (u32)max_det_extras;
1312 
1313   } else {
1314 
1315     afl->max_det_extras = MAX_DET_EXTRAS;
1316 
1317   }
1318 
1319   if (afl->afl_env.afl_testcache_size) {
1320 
1321     afl->q_testcase_max_cache_size =
1322         (u64)atoi(afl->afl_env.afl_testcache_size) * 1048576;
1323 
1324   }
1325 
1326   if (afl->afl_env.afl_testcache_entries) {
1327 
1328     afl->q_testcase_max_cache_entries =
1329         (u32)atoi(afl->afl_env.afl_testcache_entries);
1330 
1331     // user_set_cache = 1;
1332 
1333   }
1334 
1335   if (!afl->afl_env.afl_testcache_size || !afl->afl_env.afl_testcache_entries) {
1336 
1337     afl->afl_env.afl_testcache_entries = 0;
1338     afl->afl_env.afl_testcache_size = 0;
1339 
1340   }
1341 
1342   if (!afl->q_testcase_max_cache_size) {
1343 
1344     ACTF(
1345         "No testcache was configured. it is recommended to use a testcache, it "
1346         "improves performance: set AFL_TESTCACHE_SIZE=(value in MB)");
1347 
1348   } else if (afl->q_testcase_max_cache_size < 2 * MAX_FILE) {
1349 
1350     FATAL("AFL_TESTCACHE_SIZE must be set to %u or more, or 0 to disable",
1351           (2 * MAX_FILE) % 1048576 == 0 ? (2 * MAX_FILE) / 1048576
1352                                         : 1 + ((2 * MAX_FILE) / 1048576));
1353 
1354   } else {
1355 
1356     OKF("Enabled testcache with %llu MB",
1357         afl->q_testcase_max_cache_size / 1048576);
1358 
1359   }
1360 
1361   if (afl->afl_env.afl_forksrv_init_tmout) {
1362 
1363     afl->fsrv.init_tmout = atoi(afl->afl_env.afl_forksrv_init_tmout);
1364     if (!afl->fsrv.init_tmout) {
1365 
1366       FATAL("Invalid value of AFL_FORKSRV_INIT_TMOUT");
1367 
1368     }
1369 
1370   } else {
1371 
1372     afl->fsrv.init_tmout = afl->fsrv.exec_tmout * FORK_WAIT_MULT;
1373 
1374   }
1375 
1376   if (afl->afl_env.afl_crash_exitcode) {
1377 
1378     long exitcode = strtol(afl->afl_env.afl_crash_exitcode, NULL, 10);
1379     if ((!exitcode && (errno == EINVAL || errno == ERANGE)) ||
1380         exitcode < -127 || exitcode > 128) {
1381 
1382       FATAL("Invalid crash exitcode, expected -127 to 128, but got %s",
1383             afl->afl_env.afl_crash_exitcode);
1384 
1385     }
1386 
1387     afl->fsrv.uses_crash_exitcode = true;
1388     // WEXITSTATUS is 8 bit unsigned
1389     afl->fsrv.crash_exitcode = (u8)exitcode;
1390 
1391   }
1392 
1393   if (afl->non_instrumented_mode == 2 && afl->no_forkserver) {
1394 
1395     FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
1396 
1397   }
1398 
1399   afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
1400 
1401   if (getenv("LD_PRELOAD")) {
1402 
1403     WARNF(
1404         "LD_PRELOAD is set, are you sure that is what to you want to do "
1405         "instead of using AFL_PRELOAD?");
1406 
1407   }
1408 
1409   if (afl->afl_env.afl_preload) {
1410 
1411     if (afl->fsrv.qemu_mode) {
1412 
1413       /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
1414 
1415     } else if (afl->fsrv.frida_mode) {
1416 
1417       afl_preload = getenv("AFL_PRELOAD");
1418       u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
1419       OKF("Injecting %s ...", frida_binary);
1420       if (afl_preload) {
1421 
1422         if (afl->fsrv.frida_asan) {
1423 
1424           OKF("Using Frida Address Sanitizer Mode");
1425 
1426           fasan_check_afl_preload(afl_preload);
1427 
1428           setenv("ASAN_OPTIONS", "detect_leaks=false", 1);
1429 
1430         }
1431 
1432         u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
1433         OKF("Injecting %s ...", frida_binary);
1434         frida_afl_preload = alloc_printf("%s:%s", afl_preload, frida_binary);
1435 
1436         ck_free(frida_binary);
1437 
1438         setenv("LD_PRELOAD", frida_afl_preload, 1);
1439         setenv("DYLD_INSERT_LIBRARIES", frida_afl_preload, 1);
1440 
1441       }
1442 
1443     } else {
1444 
1445       setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
1446       setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
1447 
1448     }
1449 
1450   } else if (afl->fsrv.frida_mode) {
1451 
1452     if (afl->fsrv.frida_asan) {
1453 
1454       OKF("Using Frida Address Sanitizer Mode");
1455       FATAL(
1456           "Address Sanitizer DSO must be loaded using AFL_PRELOAD in Frida "
1457           "Address Sanitizer Mode");
1458 
1459     } else {
1460 
1461       u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
1462       OKF("Injecting %s ...", frida_binary);
1463       setenv("LD_PRELOAD", frida_binary, 1);
1464       setenv("DYLD_INSERT_LIBRARIES", frida_binary, 1);
1465       ck_free(frida_binary);
1466 
1467     }
1468 
1469   }
1470 
1471   if (getenv("AFL_LD_PRELOAD")) {
1472 
1473     FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");
1474 
1475   }
1476 
1477   if (afl->afl_env.afl_target_env &&
1478       !extract_and_set_env(afl->afl_env.afl_target_env)) {
1479 
1480     FATAL("Bad value of AFL_TARGET_ENV");
1481 
1482   }
1483 
1484   save_cmdline(afl, argc, argv);
1485 
1486   fix_up_banner(afl, argv[optind]);
1487 
1488   check_if_tty(afl);
1489   if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
1490 
1491   if (afl->afl_env.afl_custom_mutator_only) {
1492 
1493     /* This ensures we don't proceed to havoc/splice */
1494     afl->custom_only = 1;
1495 
1496     /* Ensure we also skip all deterministic steps */
1497     afl->skip_deterministic = 1;
1498 
1499   }
1500 
1501   check_crash_handling();
1502   check_cpu_governor(afl);
1503 
1504   get_core_count(afl);
1505 
1506   atexit(at_exit);
1507 
1508   setup_dirs_fds(afl);
1509 
1510   #ifdef HAVE_AFFINITY
1511   bind_to_free_cpu(afl);
1512   #endif                                                   /* HAVE_AFFINITY */
1513 
1514   #ifdef __HAIKU__
1515   /* Prioritizes performance over power saving */
1516   set_scheduler_mode(SCHEDULER_MODE_LOW_LATENCY);
1517   #endif
1518 
1519   #ifdef __APPLE__
1520   if (pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0) != 0) {
1521 
1522     WARNF("general thread priority settings failed");
1523 
1524   }
1525 
1526   #endif
1527 
1528   init_count_class16();
1529 
1530   if (afl->is_main_node && check_main_node_exists(afl) == 1) {
1531 
1532     WARNF("it is wasteful to run more than one main node!");
1533     sleep(1);
1534 
1535   } else if (!auto_sync && afl->is_secondary_node &&
1536 
1537              check_main_node_exists(afl) == 0) {
1538 
1539     WARNF(
1540         "no -M main node found. It is recommended to run exactly one main "
1541         "instance.");
1542     sleep(1);
1543 
1544   }
1545 
1546   #ifdef RAND_TEST_VALUES
1547   u32 counter;
1548   for (counter = 0; counter < 100000; counter++)
1549     printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
1550   #endif
1551 
1552   setup_custom_mutators(afl);
1553 
1554   write_setup_file(afl, argc, argv);
1555 
1556   setup_cmdline_file(afl, argv + optind);
1557 
1558   read_testcases(afl, NULL);
1559   // read_foreign_testcases(afl, 1); for the moment dont do this
1560   OKF("Loaded a total of %u seeds.", afl->queued_paths);
1561 
1562   pivot_inputs(afl);
1563 
1564   if (!afl->timeout_given) { find_timeout(afl); }  // only for resumes!
1565 
1566   if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
1567       !afl->in_place_resume) {
1568 
1569     char tmpfile[PATH_MAX];
1570 
1571     if (afl->file_extension) {
1572 
1573       snprintf(tmpfile, PATH_MAX, "%s/.cur_input.%s", afl->tmp_dir,
1574                afl->file_extension);
1575 
1576     } else {
1577 
1578       snprintf(tmpfile, PATH_MAX, "%s/.cur_input", afl->tmp_dir);
1579 
1580     }
1581 
1582     /* there is still a race condition here, but well ... */
1583     if (access(tmpfile, F_OK) != -1) {
1584 
1585       FATAL(
1586           "AFL_TMPDIR already has an existing temporary input file: %s - if "
1587           "this is not from another instance, then just remove the file.",
1588           tmpfile);
1589 
1590     }
1591 
1592   } else {
1593 
1594     afl->tmp_dir = afl->out_dir;
1595 
1596   }
1597 
1598   /* If we don't have a file name chosen yet, use a safe default. */
1599 
1600   if (!afl->fsrv.out_file) {
1601 
1602     u32 j = optind + 1;
1603     while (argv[j]) {
1604 
1605       u8 *aa_loc = strstr(argv[j], "@@");
1606 
1607       if (aa_loc && !afl->fsrv.out_file) {
1608 
1609         afl->fsrv.use_stdin = 0;
1610 
1611         if (afl->file_extension) {
1612 
1613           afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir,
1614                                             afl->file_extension);
1615 
1616         } else {
1617 
1618           afl->fsrv.out_file = alloc_printf("%s/.cur_input", afl->tmp_dir);
1619 
1620         }
1621 
1622         detect_file_args(argv + optind + 1, afl->fsrv.out_file,
1623                          &afl->fsrv.use_stdin);
1624         break;
1625 
1626       }
1627 
1628       ++j;
1629 
1630     }
1631 
1632   }
1633 
1634   if (!afl->fsrv.out_file) { setup_stdio_file(afl); }
1635 
1636   if (afl->cmplog_binary) {
1637 
1638     if (afl->unicorn_mode) {
1639 
1640       FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry");
1641 
1642     }
1643 
1644     if (!afl->fsrv.qemu_mode && !afl->fsrv.frida_mode &&
1645         !afl->non_instrumented_mode) {
1646 
1647       check_binary(afl, afl->cmplog_binary);
1648 
1649     }
1650 
1651   }
1652 
1653   check_binary(afl, argv[optind]);
1654 
1655   #ifdef AFL_PERSISTENT_RECORD
1656   if (unlikely(afl->fsrv.persistent_record)) {
1657 
1658     if (!getenv(PERSIST_ENV_VAR)) {
1659 
1660       FATAL(
1661           "Target binary is not compiled in persistent mode, "
1662           "AFL_PERSISTENT_RECORD makes no sense.");
1663 
1664     }
1665 
1666     afl->fsrv.persistent_record_dir = alloc_printf("%s/crashes", afl->out_dir);
1667 
1668   }
1669 
1670   #endif
1671 
1672   if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
1673 
1674   afl->start_time = get_cur_time();
1675 
1676   if (afl->fsrv.qemu_mode) {
1677 
1678     if (afl->use_wine) {
1679 
1680       use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind,
1681                                argv + optind);
1682 
1683     } else {
1684 
1685       use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind,
1686                                argv + optind);
1687 
1688     }
1689 
1690   } else {
1691 
1692     use_argv = argv + optind;
1693 
1694   }
1695 
1696   if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
1697       afl->fsrv.frida_mode || afl->unicorn_mode) {
1698 
1699     map_size = afl->fsrv.map_size = MAP_SIZE;
1700     afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
1701     afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
1702     afl->virgin_crash = ck_realloc(afl->virgin_crash, map_size);
1703     afl->var_bytes = ck_realloc(afl->var_bytes, map_size);
1704     afl->top_rated = ck_realloc(afl->top_rated, map_size * sizeof(void *));
1705     afl->clean_trace = ck_realloc(afl->clean_trace, map_size);
1706     afl->clean_trace_custom = ck_realloc(afl->clean_trace_custom, map_size);
1707     afl->first_trace = ck_realloc(afl->first_trace, map_size);
1708     afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
1709 
1710   }
1711 
1712   afl->argv = use_argv;
1713   afl->fsrv.trace_bits =
1714       afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->non_instrumented_mode);
1715 
1716   if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
1717       !afl->unicorn_mode && !afl->fsrv.frida_mode &&
1718       !afl->afl_env.afl_skip_bin_check) {
1719 
1720     if (map_size <= DEFAULT_SHMEM_SIZE) {
1721 
1722       afl->fsrv.map_size = DEFAULT_SHMEM_SIZE;  // dummy temporary value
1723       char vbuf[16];
1724       snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE);
1725       setenv("AFL_MAP_SIZE", vbuf, 1);
1726 
1727     }
1728 
1729     u32 new_map_size = afl_fsrv_get_mapsize(
1730         &afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child);
1731 
1732     // only reinitialize if the map needs to be larger than what we have.
1733     if (map_size < new_map_size) {
1734 
1735       OKF("Re-initializing maps to %u bytes", new_map_size);
1736 
1737       afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
1738       afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
1739       afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
1740       afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size);
1741       afl->top_rated =
1742           ck_realloc(afl->top_rated, new_map_size * sizeof(void *));
1743       afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size);
1744       afl->clean_trace_custom =
1745           ck_realloc(afl->clean_trace_custom, new_map_size);
1746       afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
1747       afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
1748 
1749       afl_fsrv_kill(&afl->fsrv);
1750       afl_shm_deinit(&afl->shm);
1751       afl->fsrv.map_size = new_map_size;
1752       afl->fsrv.trace_bits =
1753           afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode);
1754       setenv("AFL_NO_AUTODICT", "1", 1);  // loaded already
1755       afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon,
1756                      afl->afl_env.afl_debug_child);
1757 
1758       map_size = new_map_size;
1759 
1760     }
1761 
1762   }
1763 
1764   if (afl->cmplog_binary) {
1765 
1766     ACTF("Spawning cmplog forkserver");
1767     afl_fsrv_init_dup(&afl->cmplog_fsrv, &afl->fsrv);
1768     // TODO: this is semi-nice
1769     afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
1770     afl->cmplog_fsrv.qemu_mode = afl->fsrv.qemu_mode;
1771     afl->cmplog_fsrv.frida_mode = afl->fsrv.frida_mode;
1772     afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
1773     afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
1774 
1775     if ((map_size <= DEFAULT_SHMEM_SIZE ||
1776          afl->cmplog_fsrv.map_size < map_size) &&
1777         !afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
1778         !afl->fsrv.frida_mode && !afl->unicorn_mode &&
1779         !afl->afl_env.afl_skip_bin_check) {
1780 
1781       afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
1782       char vbuf[16];
1783       snprintf(vbuf, sizeof(vbuf), "%u", afl->cmplog_fsrv.map_size);
1784       setenv("AFL_MAP_SIZE", vbuf, 1);
1785 
1786     }
1787 
1788     u32 new_map_size =
1789         afl_fsrv_get_mapsize(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
1790                              afl->afl_env.afl_debug_child);
1791 
1792     // only reinitialize when it needs to be larger
1793     if (map_size < new_map_size) {
1794 
1795       OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
1796 
1797       afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
1798       afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
1799       afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
1800       afl->var_bytes = ck_realloc(afl->var_bytes, new_map_size);
1801       afl->top_rated =
1802           ck_realloc(afl->top_rated, new_map_size * sizeof(void *));
1803       afl->clean_trace = ck_realloc(afl->clean_trace, new_map_size);
1804       afl->clean_trace_custom =
1805           ck_realloc(afl->clean_trace_custom, new_map_size);
1806       afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
1807       afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
1808 
1809       afl_fsrv_kill(&afl->fsrv);
1810       afl_fsrv_kill(&afl->cmplog_fsrv);
1811       afl_shm_deinit(&afl->shm);
1812 
1813       afl->cmplog_fsrv.map_size = new_map_size;  // non-cmplog stays the same
1814       map_size = new_map_size;
1815 
1816       setenv("AFL_NO_AUTODICT", "1", 1);  // loaded already
1817       afl->fsrv.trace_bits =
1818           afl_shm_init(&afl->shm, new_map_size, afl->non_instrumented_mode);
1819       afl->cmplog_fsrv.trace_bits = afl->fsrv.trace_bits;
1820       afl_fsrv_start(&afl->fsrv, afl->argv, &afl->stop_soon,
1821                      afl->afl_env.afl_debug_child);
1822       afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
1823                      afl->afl_env.afl_debug_child);
1824 
1825     }
1826 
1827     OKF("Cmplog forkserver successfully started");
1828 
1829   }
1830 
1831   load_auto(afl);
1832 
1833   if (extras_dir_cnt) {
1834 
1835     for (u8 i = 0; i < extras_dir_cnt; i++) {
1836 
1837       load_extras(afl, extras_dir[i]);
1838 
1839     }
1840 
1841   }
1842 
1843   deunicode_extras(afl);
1844   dedup_extras(afl);
1845   if (afl->extras_cnt) { OKF("Loaded a total of %u extras.", afl->extras_cnt); }
1846 
1847   // after we have the correct bitmap size we can read the bitmap -B option
1848   // and set the virgin maps
1849   if (afl->in_bitmap) {
1850 
1851     read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size);
1852 
1853   } else {
1854 
1855     memset(afl->virgin_bits, 255, map_size);
1856 
1857   }
1858 
1859   memset(afl->virgin_tmout, 255, map_size);
1860   memset(afl->virgin_crash, 255, map_size);
1861 
1862   perform_dry_run(afl);
1863 
1864   if (afl->q_testcase_max_cache_entries) {
1865 
1866     afl->q_testcase_cache =
1867         ck_alloc(afl->q_testcase_max_cache_entries * sizeof(size_t));
1868     if (!afl->q_testcase_cache) { PFATAL("malloc failed for cache entries"); }
1869 
1870   }
1871 
1872   cull_queue(afl);
1873 
1874   // ensure we have at least one seed that is not disabled.
1875   u32 entry, valid_seeds = 0;
1876   for (entry = 0; entry < afl->queued_paths; ++entry)
1877     if (!afl->queue_buf[entry]->disabled) { ++valid_seeds; }
1878 
1879   if (!afl->pending_not_fuzzed || !valid_seeds) {
1880 
1881     FATAL("We need at least one valid input seed that does not crash!");
1882 
1883   }
1884 
1885   if (afl->timeout_given == 2) {  // -t ...+ option
1886 
1887     if (valid_seeds == 1) {
1888 
1889       WARNF(
1890           "Only one valid seed is present, auto-calculating the timeout is "
1891           "disabled!");
1892       afl->timeout_given = 1;
1893 
1894     } else {
1895 
1896       u64 max_ms = 0;
1897 
1898       for (entry = 0; entry < afl->queued_paths; ++entry)
1899         if (!afl->queue_buf[entry]->disabled)
1900           if (afl->queue_buf[entry]->exec_us > max_ms)
1901             max_ms = afl->queue_buf[entry]->exec_us;
1902 
1903       afl->fsrv.exec_tmout = max_ms;
1904 
1905     }
1906 
1907   }
1908 
1909   show_init_stats(afl);
1910 
1911   if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl);
1912 
1913   afl->start_time = get_cur_time();
1914   if (afl->in_place_resume || afl->afl_env.afl_autoresume) {
1915 
1916     load_stats_file(afl);
1917 
1918   }
1919 
1920   write_stats_file(afl, 0, 0, 0, 0);
1921   maybe_update_plot_file(afl, 0, 0, 0);
1922   save_auto(afl);
1923 
1924   if (afl->stop_soon) { goto stop_fuzzing; }
1925 
1926   /* Woop woop woop */
1927 
1928   if (!afl->not_on_tty) {
1929 
1930     sleep(1);
1931     if (afl->stop_soon) { goto stop_fuzzing; }
1932 
1933   }
1934 
1935   // (void)nice(-20);  // does not improve the speed
1936   // real start time, we reset, so this works correctly with -V
1937   afl->start_time = get_cur_time();
1938 
1939   u32 runs_in_current_cycle = (u32)-1;
1940   u32 prev_queued_paths = 0;
1941   u8  skipped_fuzz;
1942 
1943   #ifdef INTROSPECTION
1944   char ifn[4096];
1945   snprintf(ifn, sizeof(ifn), "%s/introspection.txt", afl->out_dir);
1946   if ((afl->introspection_file = fopen(ifn, "w")) == NULL) {
1947 
1948     PFATAL("could not create '%s'", ifn);
1949 
1950   }
1951 
1952   setvbuf(afl->introspection_file, NULL, _IONBF, 0);
1953   OKF("Writing mutation introspection to '%s'", ifn);
1954   #endif
1955 
1956   while (likely(!afl->stop_soon)) {
1957 
1958     cull_queue(afl);
1959 
1960     if (unlikely((!afl->old_seed_selection &&
1961                   runs_in_current_cycle > afl->queued_paths) ||
1962                  (afl->old_seed_selection && !afl->queue_cur))) {
1963 
1964       if (unlikely((afl->last_sync_cycle < afl->queue_cycle ||
1965                     (!afl->queue_cycle && afl->afl_env.afl_import_first)) &&
1966                    afl->sync_id)) {
1967 
1968         sync_fuzzers(afl);
1969 
1970       }
1971 
1972       ++afl->queue_cycle;
1973       runs_in_current_cycle = (u32)-1;
1974       afl->cur_skipped_paths = 0;
1975 
1976       if (unlikely(afl->old_seed_selection)) {
1977 
1978         afl->current_entry = 0;
1979         while (unlikely(afl->current_entry < afl->queued_paths &&
1980                         afl->queue_buf[afl->current_entry]->disabled)) {
1981 
1982           ++afl->current_entry;
1983 
1984         }
1985 
1986         if (afl->current_entry >= afl->queued_paths) { afl->current_entry = 0; }
1987 
1988         afl->queue_cur = afl->queue_buf[afl->current_entry];
1989 
1990         if (unlikely(seek_to)) {
1991 
1992           if (unlikely(seek_to >= afl->queued_paths)) {
1993 
1994             // This should never happen.
1995             FATAL("BUG: seek_to location out of bounds!\n");
1996 
1997           }
1998 
1999           afl->current_entry = seek_to;
2000           afl->queue_cur = afl->queue_buf[seek_to];
2001           seek_to = 0;
2002 
2003         }
2004 
2005       }
2006 
2007       if (unlikely(afl->not_on_tty)) {
2008 
2009         ACTF("Entering queue cycle %llu.", afl->queue_cycle);
2010         fflush(stdout);
2011 
2012       }
2013 
2014       /* If we had a full queue cycle with no new finds, try
2015          recombination strategies next. */
2016 
2017       if (unlikely(afl->queued_paths == prev_queued
2018                    /* FIXME TODO BUG: && (get_cur_time() - afl->start_time) >=
2019                       3600 */
2020                    )) {
2021 
2022         if (afl->use_splicing) {
2023 
2024           ++afl->cycles_wo_finds;
2025 
2026           if (unlikely(afl->shm.cmplog_mode &&
2027                        afl->cmplog_max_filesize < MAX_FILE)) {
2028 
2029             afl->cmplog_max_filesize <<= 4;
2030 
2031           }
2032 
2033           switch (afl->expand_havoc) {
2034 
2035             case 0:
2036               // this adds extra splicing mutation options to havoc mode
2037               afl->expand_havoc = 1;
2038               break;
2039             case 1:
2040               // add MOpt mutator
2041               /*
2042               if (afl->limit_time_sig == 0 && !afl->custom_only &&
2043                   !afl->python_only) {
2044 
2045                 afl->limit_time_sig = -1;
2046                 afl->limit_time_puppet = 0;
2047 
2048               }
2049 
2050               */
2051               afl->expand_havoc = 2;
2052               if (afl->cmplog_lvl && afl->cmplog_lvl < 2) afl->cmplog_lvl = 2;
2053               break;
2054             case 2:
2055               // increase havoc mutations per fuzz attempt
2056               afl->havoc_stack_pow2++;
2057               afl->expand_havoc = 3;
2058               break;
2059             case 3:
2060               // further increase havoc mutations per fuzz attempt
2061               afl->havoc_stack_pow2++;
2062               afl->expand_havoc = 4;
2063               break;
2064             case 4:
2065               afl->expand_havoc = 5;
2066               // if (afl->cmplog_lvl && afl->cmplog_lvl < 3) afl->cmplog_lvl =
2067               // 3;
2068               break;
2069             case 5:
2070               // nothing else currently
2071               break;
2072 
2073           }
2074 
2075         } else {
2076 
2077   #ifndef NO_SPLICING
2078           afl->use_splicing = 1;
2079   #else
2080           afl->use_splicing = 0;
2081   #endif
2082 
2083         }
2084 
2085       } else {
2086 
2087         afl->cycles_wo_finds = 0;
2088 
2089       }
2090 
2091   #ifdef INTROSPECTION
2092       fprintf(afl->introspection_file,
2093               "CYCLE cycle=%llu cycle_wo_finds=%llu expand_havoc=%u queue=%u\n",
2094               afl->queue_cycle, afl->cycles_wo_finds, afl->expand_havoc,
2095               afl->queued_paths);
2096   #endif
2097 
2098       if (afl->cycle_schedules) {
2099 
2100         /* we cannot mix non-AFLfast schedules with others */
2101 
2102         switch (afl->schedule) {
2103 
2104           case EXPLORE:
2105             afl->schedule = EXPLOIT;
2106             break;
2107           case EXPLOIT:
2108             afl->schedule = MMOPT;
2109             break;
2110           case MMOPT:
2111             afl->schedule = SEEK;
2112             break;
2113           case SEEK:
2114             afl->schedule = EXPLORE;
2115             break;
2116           case FAST:
2117             afl->schedule = COE;
2118             break;
2119           case COE:
2120             afl->schedule = LIN;
2121             break;
2122           case LIN:
2123             afl->schedule = QUAD;
2124             break;
2125           case QUAD:
2126             afl->schedule = RARE;
2127             break;
2128           case RARE:
2129             afl->schedule = FAST;
2130             break;
2131 
2132         }
2133 
2134         // we must recalculate the scores of all queue entries
2135         for (u32 i = 0; i < afl->queued_paths; i++) {
2136 
2137           if (likely(!afl->queue_buf[i]->disabled)) {
2138 
2139             update_bitmap_score(afl, afl->queue_buf[i]);
2140 
2141           }
2142 
2143         }
2144 
2145       }
2146 
2147       prev_queued = afl->queued_paths;
2148 
2149     }
2150 
2151     ++runs_in_current_cycle;
2152 
2153     do {
2154 
2155       if (likely(!afl->old_seed_selection)) {
2156 
2157         if (unlikely(prev_queued_paths < afl->queued_paths ||
2158                      afl->reinit_table)) {
2159 
2160           // we have new queue entries since the last run, recreate alias table
2161           prev_queued_paths = afl->queued_paths;
2162           create_alias_table(afl);
2163 
2164         }
2165 
2166         afl->current_entry = select_next_queue_entry(afl);
2167         afl->queue_cur = afl->queue_buf[afl->current_entry];
2168 
2169       }
2170 
2171       skipped_fuzz = fuzz_one(afl);
2172 
2173       if (unlikely(!afl->stop_soon && exit_1)) { afl->stop_soon = 2; }
2174 
2175       if (unlikely(afl->old_seed_selection)) {
2176 
2177         while (++afl->current_entry < afl->queued_paths &&
2178                afl->queue_buf[afl->current_entry]->disabled)
2179           ;
2180         if (unlikely(afl->current_entry >= afl->queued_paths ||
2181                      afl->queue_buf[afl->current_entry] == NULL ||
2182                      afl->queue_buf[afl->current_entry]->disabled))
2183           afl->queue_cur = NULL;
2184         else
2185           afl->queue_cur = afl->queue_buf[afl->current_entry];
2186 
2187       }
2188 
2189     } while (skipped_fuzz && afl->queue_cur && !afl->stop_soon);
2190 
2191     if (likely(!afl->stop_soon && afl->sync_id)) {
2192 
2193       if (likely(afl->skip_deterministic)) {
2194 
2195         if (unlikely(afl->is_main_node)) {
2196 
2197           if (unlikely(get_cur_time() >
2198                        (SYNC_TIME >> 1) + afl->last_sync_time)) {
2199 
2200             if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) {
2201 
2202               sync_fuzzers(afl);
2203 
2204             }
2205 
2206           }
2207 
2208         } else {
2209 
2210           if (unlikely(get_cur_time() > SYNC_TIME + afl->last_sync_time)) {
2211 
2212             if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
2213 
2214           }
2215 
2216         }
2217 
2218       } else {
2219 
2220         sync_fuzzers(afl);
2221 
2222       }
2223 
2224     }
2225 
2226   }
2227 
2228   write_bitmap(afl);
2229   save_auto(afl);
2230 
2231 stop_fuzzing:
2232 
2233   afl->force_ui_update = 1;  // ensure the screen is reprinted
2234   show_stats(afl);           // print the screen one last time
2235 
2236   SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
2237        afl->stop_soon == 2 ? "programmatically" : "by user");
2238 
2239   if (afl->most_time_key == 2) {
2240 
2241     SAYF(cYEL "[!] " cRST "Time limit was reached\n");
2242 
2243   }
2244 
2245   if (afl->most_execs_key == 2) {
2246 
2247     SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
2248 
2249   }
2250 
2251   /* Running for more than 30 minutes but still doing first cycle? */
2252 
2253   if (afl->queue_cycle == 1 &&
2254       get_cur_time() - afl->start_time > 30 * 60 * 1000) {
2255 
2256     SAYF("\n" cYEL "[!] " cRST
2257          "Stopped during the first cycle, results may be incomplete.\n"
2258          "    (For info on resuming, see %s/README.md)\n",
2259          doc_path);
2260 
2261   }
2262 
2263   #ifdef PROFILING
2264   SAYF(cYEL "[!] " cRST
2265             "Profiling information: %llu ms total work, %llu ns/run\n",
2266        time_spent_working / 1000000,
2267        time_spent_working / afl->fsrv.total_execs);
2268   #endif
2269 
2270   if (afl->is_main_node) {
2271 
2272     u8 path[PATH_MAX];
2273     sprintf(path, "%s/is_main_node", afl->out_dir);
2274     unlink(path);
2275 
2276   }
2277 
2278   if (frida_afl_preload) { ck_free(frida_afl_preload); }
2279 
2280   fclose(afl->fsrv.plot_file);
2281   destroy_queue(afl);
2282   destroy_extras(afl);
2283   destroy_custom_mutators(afl);
2284   afl_shm_deinit(&afl->shm);
2285 
2286   if (afl->shm_fuzz) {
2287 
2288     afl_shm_deinit(afl->shm_fuzz);
2289     ck_free(afl->shm_fuzz);
2290 
2291   }
2292 
2293   afl_fsrv_deinit(&afl->fsrv);
2294 
2295   /* remove tmpfile */
2296   if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) {
2297 
2298     (void)unlink(afl->fsrv.out_file);
2299 
2300   }
2301 
2302   if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
2303   ck_free(afl->fsrv.target_path);
2304   ck_free(afl->fsrv.out_file);
2305   ck_free(afl->sync_id);
2306   if (afl->q_testcase_cache) { ck_free(afl->q_testcase_cache); }
2307   afl_state_deinit(afl);
2308   free(afl);                                                 /* not tracked */
2309 
2310   argv_cpy_free(argv);
2311 
2312   alloc_report();
2313 
2314   OKF("We're done here. Have a nice day!\n");
2315 
2316   exit(0);
2317 
2318 }
2319 
2320 #endif                                                          /* !AFL_LIB */
2321 
2322