xref: /aosp_15_r20/external/AFLplusplus/src/afl-showmap.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - map display utility
3    ------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Forkserver design by Jann Horn <[email protected]>
8 
9    Now maintained by Marc Heuse <[email protected]>,
10                         Heiko Eißfeldt <[email protected]> and
11                         Andrea Fioraldi <[email protected]> and
12                         Dominik Maier <[email protected]>
13 
14    Copyright 2016, 2017 Google Inc. All rights reserved.
15    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
16 
17    Licensed under the Apache License, Version 2.0 (the "License");
18    you may not use this file except in compliance with the License.
19    You may obtain a copy of the License at:
20 
21      https://www.apache.org/licenses/LICENSE-2.0
22 
23    A very simple tool that runs the targeted binary and displays
24    the contents of the trace bitmap in a human-readable form. Useful in
25    scripts to eliminate redundant inputs and perform other checks.
26 
27    Exit code is 2 if the target program crashes; 1 if it times out or
28    there is a problem executing it; or 0 if execution is successful.
29 
30  */
31 
32 #define AFL_MAIN
33 #define AFL_SHOWMAP
34 
35 #include "config.h"
36 #include "afl-fuzz.h"
37 #include "types.h"
38 #include "debug.h"
39 #include "alloc-inl.h"
40 #include "hash.h"
41 #include "sharedmem.h"
42 #include "forkserver.h"
43 #include "common.h"
44 #include "hash.h"
45 
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <time.h>
51 #include <errno.h>
52 #include <signal.h>
53 #include <dirent.h>
54 #include <fcntl.h>
55 #include <limits.h>
56 
57 #include <dirent.h>
58 #include <sys/wait.h>
59 #include <sys/time.h>
60 #ifndef USEMMAP
61   #include <sys/shm.h>
62 #endif
63 #include <sys/stat.h>
64 #include <sys/types.h>
65 #include <sys/resource.h>
66 
67 static afl_state_t *afl;
68 
69 static char *stdin_file;               /* stdin file                        */
70 
71 static u8 *in_dir = NULL,              /* input folder                      */
72     *out_file = NULL,                  /* output file or directory          */
73         *at_file = NULL,               /* Substitution string for @@        */
74             *in_filelist = NULL;       /* input file list                   */
75 
76 static u8 outfile[PATH_MAX];
77 
78 static u8 *in_data,                    /* Input data                        */
79     *coverage_map;                     /* Coverage map                      */
80 
81 static u64 total;                      /* tuple content information         */
82 static u32 tcnt, highest;              /* tuple content information         */
83 
84 static u32 in_len;                     /* Input data length                 */
85 
86 static u32 map_size = MAP_SIZE, timed_out = 0;
87 
88 static bool quiet_mode,                /* Hide non-essential messages?      */
89     edges_only,                        /* Ignore hit counts?                */
90     raw_instr_output,                  /* Do not apply AFL filters          */
91     cmin_mode,                         /* Generate output in afl-cmin mode? */
92     binary_mode,                       /* Write output as a binary map      */
93     keep_cores,                        /* Allow coredumps?                  */
94     remove_shm = true,                 /* remove shmem?                     */
95     collect_coverage,                  /* collect coverage                  */
96     have_coverage,                     /* have coverage?                    */
97     no_classify,                       /* do not classify counts            */
98     debug,                             /* debug mode                        */
99     print_filenames,                   /* print the current filename        */
100     wait_for_gdb;
101 
102 static volatile u8 stop_soon,          /* Ctrl-C pressed?                   */
103     child_crashed;                     /* Child crashed?                    */
104 
105 static sharedmem_t       shm;
106 static afl_forkserver_t *fsrv;
107 static sharedmem_t      *shm_fuzz;
108 
109 /* Classify tuple counts. Instead of mapping to individual bits, as in
110    afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
111 
112 static const u8 count_class_human[256] = {
113 
114     [0] = 0,          [1] = 1,        [2] = 2,         [3] = 3,
115     [4 ... 7] = 4,    [8 ... 15] = 5, [16 ... 31] = 6, [32 ... 127] = 7,
116     [128 ... 255] = 8
117 
118 };
119 
120 static const u8 count_class_binary[256] = {
121 
122     [0] = 0,
123     [1] = 1,
124     [2] = 2,
125     [3] = 4,
126     [4 ... 7] = 8,
127     [8 ... 15] = 16,
128     [16 ... 31] = 32,
129     [32 ... 127] = 64,
130     [128 ... 255] = 128
131 
132 };
133 
kill_child()134 static void kill_child() {
135 
136   timed_out = 1;
137   if (fsrv->child_pid > 0) {
138 
139     kill(fsrv->child_pid, fsrv->child_kill_signal);
140     fsrv->child_pid = -1;
141 
142   }
143 
144 }
145 
146 /* dummy functions */
write_to_testcase(afl_state_t * afl,void ** mem,u32 a,u32 b)147 u32 write_to_testcase(afl_state_t *afl, void **mem, u32 a, u32 b) {
148 
149   (void)afl;
150   (void)mem;
151   return a + b;
152 
153 }
154 
show_stats(afl_state_t * afl)155 void show_stats(afl_state_t *afl) {
156 
157   (void)afl;
158 
159 }
160 
update_bitmap_score(afl_state_t * afl,struct queue_entry * q)161 void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
162 
163   (void)afl;
164   (void)q;
165 
166 }
167 
fuzz_run_target(afl_state_t * afl,afl_forkserver_t * fsrv,u32 i)168 fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
169                                   u32 i) {
170 
171   (void)afl;
172   (void)fsrv;
173   (void)i;
174   return 0;
175 
176 }
177 
classify_counts(afl_forkserver_t * fsrv)178 void classify_counts(afl_forkserver_t *fsrv) {
179 
180   u8       *mem = fsrv->trace_bits;
181   const u8 *map = binary_mode ? count_class_binary : count_class_human;
182 
183   u32 i = map_size;
184 
185   if (edges_only) {
186 
187     while (i--) {
188 
189       if (*mem) { *mem = 1; }
190       mem++;
191 
192     }
193 
194   } else if (!raw_instr_output) {
195 
196     while (i--) {
197 
198       *mem = map[*mem];
199       mem++;
200 
201     }
202 
203   }
204 
205 }
206 
deinit_shmem(afl_forkserver_t * fsrv,sharedmem_t * shm_fuzz)207 static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
208                                  sharedmem_t      *shm_fuzz) {
209 
210   afl_shm_deinit(shm_fuzz);
211   fsrv->support_shmem_fuzz = 0;
212   fsrv->shmem_fuzz_len = NULL;
213   fsrv->shmem_fuzz = NULL;
214   ck_free(shm_fuzz);
215   return NULL;
216 
217 }
218 
219 /* Get rid of temp files (atexit handler). */
220 
at_exit_handler(void)221 static void at_exit_handler(void) {
222 
223   if (stdin_file) { unlink(stdin_file); }
224 
225   if (remove_shm) {
226 
227     if (shm.map) afl_shm_deinit(&shm);
228     if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
229 
230   }
231 
232   afl_fsrv_killall();
233 
234 }
235 
236 /* Analyze results. */
237 
analyze_results(afl_forkserver_t * fsrv)238 static void analyze_results(afl_forkserver_t *fsrv) {
239 
240   u32 i;
241   for (i = 0; i < map_size; i++) {
242 
243     if (fsrv->trace_bits[i]) {
244 
245       total += fsrv->trace_bits[i];
246       if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i];
247       // if (!coverage_map[i]) { coverage_map[i] = 1; }
248       coverage_map[i] |= fsrv->trace_bits[i];
249 
250     }
251 
252   }
253 
254 }
255 
256 /* Write results. */
257 
write_results_to_file(afl_forkserver_t * fsrv,u8 * outfile)258 static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
259 
260   s32 fd;
261   u32 i, ret = 0;
262 
263   u8 cco = !!getenv("AFL_CMIN_CRASHES_ONLY"),
264      caa = !!getenv("AFL_CMIN_ALLOW_ANY");
265 
266   if (!outfile || !*outfile) {
267 
268     FATAL("Output filename not set (Bug in AFL++?)");
269 
270   }
271 
272   if (cmin_mode &&
273       (fsrv->last_run_timed_out || (!caa && child_crashed != cco))) {
274 
275     if (strcmp(outfile, "-")) {
276 
277       // create empty file to prevent error messages in afl-cmin
278       fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
279       close(fd);
280 
281     }
282 
283     return ret;
284 
285   }
286 
287   if (!strncmp(outfile, "/dev/", 5)) {
288 
289     fd = open(outfile, O_WRONLY);
290 
291     if (fd < 0) { PFATAL("Unable to open '%s'", out_file); }
292 
293   } else if (!strcmp(outfile, "-")) {
294 
295     fd = dup(1);
296     if (fd < 0) { PFATAL("Unable to open stdout"); }
297 
298   } else {
299 
300     unlink(outfile);                                       /* Ignore errors */
301     fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
302     if (fd < 0) { PFATAL("Unable to create '%s'", outfile); }
303 
304   }
305 
306   if (binary_mode) {
307 
308     for (i = 0; i < map_size; i++) {
309 
310       if (fsrv->trace_bits[i]) { ret++; }
311 
312     }
313 
314     ck_write(fd, fsrv->trace_bits, map_size, outfile);
315     close(fd);
316 
317   } else {
318 
319     FILE *f = fdopen(fd, "w");
320 
321     if (!f) { PFATAL("fdopen() failed"); }
322 
323     for (i = 0; i < map_size; i++) {
324 
325       if (!fsrv->trace_bits[i]) { continue; }
326       ret++;
327 
328       total += fsrv->trace_bits[i];
329       if (highest < fsrv->trace_bits[i]) { highest = fsrv->trace_bits[i]; }
330 
331       if (cmin_mode) {
332 
333         fprintf(f, "%u%03u\n", i, fsrv->trace_bits[i]);
334 
335       } else {
336 
337         fprintf(f, "%06u:%u\n", i, fsrv->trace_bits[i]);
338 
339       }
340 
341     }
342 
343     fclose(f);
344 
345   }
346 
347   return ret;
348 
349 }
350 
pre_afl_fsrv_write_to_testcase(afl_forkserver_t * fsrv,u8 * mem,u32 len)351 void pre_afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *mem, u32 len) {
352 
353   static u8 buf[MAX_FILE];
354   u32       sent = 0;
355 
356   if (unlikely(afl->custom_mutators_count)) {
357 
358     ssize_t new_size = len;
359     u8     *new_mem = mem;
360     u8     *new_buf = NULL;
361 
362     LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
363 
364       if (el->afl_custom_post_process) {
365 
366         new_size =
367             el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf);
368 
369         if (unlikely(!new_buf || new_size <= 0)) {
370 
371           return;
372 
373         } else {
374 
375           new_mem = new_buf;
376           len = new_size;
377 
378         }
379 
380       }
381 
382     });
383 
384     if (new_mem != mem && new_mem != NULL) {
385 
386       mem = buf;
387       memcpy(mem, new_mem, new_size);
388 
389     }
390 
391     if (unlikely(afl->custom_mutators_count)) {
392 
393       LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
394 
395         if (el->afl_custom_fuzz_send) {
396 
397           el->afl_custom_fuzz_send(el->data, mem, len);
398           sent = 1;
399 
400         }
401 
402       });
403 
404     }
405 
406   }
407 
408   if (likely(!sent)) { afl_fsrv_write_to_testcase(fsrv, mem, len); }
409 
410 }
411 
412 /* Execute target application. */
413 
showmap_run_target_forkserver(afl_forkserver_t * fsrv,u8 * mem,u32 len)414 static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem,
415                                           u32 len) {
416 
417   pre_afl_fsrv_write_to_testcase(fsrv, mem, len);
418 
419   if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); }
420 
421   if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) ==
422       FSRV_RUN_ERROR) {
423 
424     FATAL("Error running target");
425 
426   }
427 
428   if (fsrv->trace_bits[0]) {
429 
430     fsrv->trace_bits[0] -= 1;
431     have_coverage = true;
432 
433   } else {
434 
435     have_coverage = false;
436 
437   }
438 
439   if (!no_classify) { classify_counts(fsrv); }
440 
441   if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); }
442 
443   if (!fsrv->last_run_timed_out && !stop_soon &&
444       WIFSIGNALED(fsrv->child_status)) {
445 
446     child_crashed = true;
447 
448   } else {
449 
450     child_crashed = false;
451 
452   }
453 
454   if (!quiet_mode) {
455 
456     if (timed_out || fsrv->last_run_timed_out) {
457 
458       SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
459       timed_out = 0;
460 
461     } else if (stop_soon) {
462 
463       SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
464 
465     } else if (child_crashed) {
466 
467       SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST,
468            WTERMSIG(fsrv->child_status));
469 
470     }
471 
472   }
473 
474   if (stop_soon) {
475 
476     SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST);
477     exit(1);
478 
479   }
480 
481 }
482 
483 /* Read initial file. */
484 
read_file(u8 * in_file)485 static u32 read_file(u8 *in_file) {
486 
487   if (print_filenames) {
488 
489     SAYF("Processing %s\n", in_file);
490     fflush(stdout);
491 
492   }
493 
494   struct stat st;
495   s32         fd = open(in_file, O_RDONLY);
496 
497   if (fd < 0) { WARNF("Unable to open '%s'", in_file); }
498 
499   if (fstat(fd, &st) || !st.st_size) {
500 
501     if (!be_quiet && !quiet_mode) {
502 
503       WARNF("Zero-sized input file '%s'.", in_file);
504 
505     }
506 
507   }
508 
509   if (st.st_size > MAX_FILE) {
510 
511     if (!be_quiet && !quiet_mode) {
512 
513       WARNF("Input file '%s' is too large, only reading %ld bytes.", in_file,
514             MAX_FILE);
515 
516     }
517 
518     in_len = MAX_FILE;
519 
520   } else {
521 
522     in_len = st.st_size;
523 
524   }
525 
526   in_data = ck_alloc_nozero(in_len);
527 
528   ck_read(fd, in_data, in_len, in_file);
529 
530   close(fd);
531 
532   // OKF("Read %u byte%s from '%s'.", in_len, in_len == 1 ? "" : "s", in_file);
533 
534   return in_len;
535 
536 }
537 
538 #ifdef __linux__
539 /* Execute the target application with an empty input (in Nyx mode). */
showmap_run_target_nyx_mode(afl_forkserver_t * fsrv)540 static void showmap_run_target_nyx_mode(afl_forkserver_t *fsrv) {
541 
542   afl_fsrv_write_to_testcase(fsrv, NULL, 0);
543 
544   if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) ==
545       FSRV_RUN_ERROR) {
546 
547     FATAL("Error running target in Nyx mode");
548 
549   }
550 
551 }
552 
553 #endif
554 
555 /* Execute target application. */
556 
showmap_run_target(afl_forkserver_t * fsrv,char ** argv)557 static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
558 
559   static struct itimerval it;
560   int                     status = 0;
561 
562   if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); }
563 
564   MEM_BARRIER();
565 
566   fsrv->child_pid = fork();
567 
568   if (fsrv->child_pid < 0) { PFATAL("fork() failed"); }
569 
570   if (!fsrv->child_pid) {
571 
572     struct rlimit r;
573 
574     if (quiet_mode) {
575 
576       s32 fd = open("/dev/null", O_RDWR);
577 
578       if (fd < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) {
579 
580         *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
581         PFATAL("Descriptor initialization failed");
582 
583       }
584 
585       close(fd);
586 
587     }
588 
589     if (fsrv->mem_limit) {
590 
591       r.rlim_max = r.rlim_cur = ((rlim_t)fsrv->mem_limit) << 20;
592 
593 #ifdef RLIMIT_AS
594 
595       setrlimit(RLIMIT_AS, &r);                            /* Ignore errors */
596 
597 #else
598 
599       setrlimit(RLIMIT_DATA, &r);                          /* Ignore errors */
600 
601 #endif                                                        /* ^RLIMIT_AS */
602 
603     }
604 
605     if (!keep_cores) {
606 
607       r.rlim_max = r.rlim_cur = 0;
608 
609     } else {
610 
611       r.rlim_max = r.rlim_cur = RLIM_INFINITY;
612 
613     }
614 
615     setrlimit(RLIMIT_CORE, &r);                            /* Ignore errors */
616 
617     if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 0); }
618 
619     setsid();
620 
621     execv(fsrv->target_path, argv);
622 
623     *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
624     exit(0);
625 
626   }
627 
628   /* Configure timeout, wait for child, cancel timeout. */
629 
630   if (fsrv->exec_tmout) {
631 
632     fsrv->last_run_timed_out = 0;
633     it.it_value.tv_sec = (fsrv->exec_tmout / 1000);
634     it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000;
635 
636     signal(SIGALRM, kill_child);
637 
638     setitimer(ITIMER_REAL, &it, NULL);
639 
640   }
641 
642   if (waitpid(fsrv->child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
643 
644   fsrv->child_pid = 0;
645   it.it_value.tv_sec = 0;
646   it.it_value.tv_usec = 0;
647   setitimer(ITIMER_REAL, &it, NULL);
648 
649   MEM_BARRIER();
650 
651   /* Clean up bitmap, analyze exit condition, etc. */
652 
653   if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) {
654 
655     FATAL("Unable to execute '%s'", argv[0]);
656 
657   }
658 
659   if (fsrv->trace_bits[0]) {
660 
661     fsrv->trace_bits[0] -= 1;
662     have_coverage = true;
663 
664   } else {
665 
666     have_coverage = false;
667 
668   }
669 
670   if (!no_classify) { classify_counts(fsrv); }
671 
672   if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); }
673 
674   if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(status)) {
675 
676     child_crashed = true;
677 
678   }
679 
680   if (!quiet_mode) {
681 
682     if (timed_out || fsrv->last_run_timed_out) {
683 
684       SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
685       timed_out = 0;
686 
687     } else if (stop_soon) {
688 
689       SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
690 
691     } else if (child_crashed) {
692 
693       SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST,
694            WTERMSIG(status));
695 
696     }
697 
698   }
699 
700 }
701 
702 /* Handle Ctrl-C and the like. */
703 
handle_stop_sig(int sig)704 static void handle_stop_sig(int sig) {
705 
706   (void)sig;
707   stop_soon = true;
708   afl_fsrv_killall();
709 
710 }
711 
712 /* Do basic preparations - persistent fds, filenames, etc. */
713 
set_up_environment(afl_forkserver_t * fsrv,char ** argv)714 static void set_up_environment(afl_forkserver_t *fsrv, char **argv) {
715 
716   char *afl_preload;
717   char *frida_afl_preload = NULL;
718 
719   set_sanitizer_defaults();
720 
721   if (get_afl_env("AFL_PRELOAD")) {
722 
723     if (fsrv->qemu_mode) {
724 
725       /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
726 
727     } else if (fsrv->frida_mode) {
728 
729       afl_preload = getenv("AFL_PRELOAD");
730       u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
731       if (afl_preload) {
732 
733         frida_afl_preload = alloc_printf("%s:%s", afl_preload, frida_binary);
734 
735       } else {
736 
737         frida_afl_preload = alloc_printf("%s", frida_binary);
738 
739       }
740 
741       ck_free(frida_binary);
742 
743       setenv("LD_PRELOAD", frida_afl_preload, 1);
744       setenv("DYLD_INSERT_LIBRARIES", frida_afl_preload, 1);
745 
746     } else {
747 
748       /* CoreSight mode uses the default behavior. */
749 
750       setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
751       setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
752 
753     }
754 
755   } else if (fsrv->frida_mode) {
756 
757     u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
758     setenv("LD_PRELOAD", frida_binary, 1);
759     setenv("DYLD_INSERT_LIBRARIES", frida_binary, 1);
760     ck_free(frida_binary);
761 
762   }
763 
764   if (frida_afl_preload) { ck_free(frida_afl_preload); }
765 
766 }
767 
768 /* Setup signal handlers, duh. */
769 
setup_signal_handlers(void)770 static void setup_signal_handlers(void) {
771 
772   struct sigaction sa;
773 
774   sa.sa_handler = NULL;
775 #ifdef SA_RESTART
776   sa.sa_flags = SA_RESTART;
777 #else
778   sa.sa_flags = 0;
779 #endif
780   sa.sa_sigaction = NULL;
781 
782   sigemptyset(&sa.sa_mask);
783 
784   /* Various ways of saying "stop". */
785 
786   sa.sa_handler = handle_stop_sig;
787   sigaction(SIGHUP, &sa, NULL);
788   sigaction(SIGINT, &sa, NULL);
789   sigaction(SIGTERM, &sa, NULL);
790 
791 }
792 
execute_testcases(u8 * dir)793 u32 execute_testcases(u8 *dir) {
794 
795   struct dirent **nl;
796   s32             nl_cnt, subdirs = 1;
797   u32             i, done = 0;
798   u8              val_buf[2][STRINGIFY_VAL_SIZE_MAX];
799 
800   if (!be_quiet) { ACTF("Scanning '%s'...", dir); }
801 
802   /* We use scandir() + alphasort() rather than readdir() because otherwise,
803      the ordering of test cases would vary somewhat randomly and would be
804      difficult to control. */
805 
806   nl_cnt = scandir(dir, &nl, NULL, alphasort);
807 
808   if (nl_cnt < 0) { return 0; }
809 
810   for (i = 0; i < (u32)nl_cnt; ++i) {
811 
812     struct stat st;
813 
814     u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
815 
816     if (lstat(fn2, &st) || access(fn2, R_OK)) {
817 
818       PFATAL("Unable to access '%s'", fn2);
819 
820     }
821 
822     /* obviously we want to skip "descending" into . and .. directories,
823        however it is a good idea to skip also directories that start with
824        a dot */
825     if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
826 
827       free(nl[i]);                                           /* not tracked */
828       done += execute_testcases(fn2);
829       ck_free(fn2);
830       continue;
831 
832     }
833 
834     if (!S_ISREG(st.st_mode) || !st.st_size) {
835 
836       free(nl[i]);
837       ck_free(fn2);
838       continue;
839 
840     }
841 
842     if (st.st_size > MAX_FILE && !be_quiet && !quiet_mode) {
843 
844       WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", fn2,
845             stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
846             stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
847 
848     }
849 
850     if (!collect_coverage)
851       snprintf(outfile, sizeof(outfile), "%s/%s", out_file, nl[i]->d_name);
852 
853     free(nl[i]);
854 
855     if (read_file(fn2)) {
856 
857       if (wait_for_gdb) {
858 
859         fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
860         fprintf(stderr, "exec: kill -CONT %d\n", getpid());
861         kill(0, SIGSTOP);
862 
863       }
864 
865       showmap_run_target_forkserver(fsrv, in_data, in_len);
866       ck_free(in_data);
867       ++done;
868 
869       if (child_crashed && debug) { WARNF("crashed: %s", fn2); }
870 
871       if (collect_coverage)
872         analyze_results(fsrv);
873       else
874         tcnt = write_results_to_file(fsrv, outfile);
875 
876     }
877 
878   }
879 
880   free(nl);                                                  /* not tracked */
881   return done;
882 
883 }
884 
execute_testcases_filelist(u8 * fn)885 u32 execute_testcases_filelist(u8 *fn) {
886 
887   u32   done = 0;
888   u8    buf[4096];
889   u8    val_buf[2][STRINGIFY_VAL_SIZE_MAX];
890   FILE *f;
891 
892   if (!be_quiet) { ACTF("Reading from '%s'...", fn); }
893 
894   if ((f = fopen(fn, "r")) == NULL) { FATAL("could not open '%s'", fn); }
895 
896   while (fgets(buf, sizeof(buf), f) != NULL) {
897 
898     struct stat st;
899     u8         *fn2 = buf, *fn3;
900 
901     while (*fn2 == ' ') {
902 
903       ++fn2;
904 
905     }
906 
907     while (*fn2 &&
908            (fn2[strlen(fn2) - 1] == '\r' || fn2[strlen(fn2) - 1] == '\n' ||
909             fn2[strlen(fn2) - 1] == ' ')) {
910 
911       fn2[strlen(fn2) - 1] = 0;
912 
913     }
914 
915     if (debug) { printf("Getting coverage for '%s'\n", fn2); }
916 
917     if (!*fn2) { continue; }
918 
919     if (lstat(fn2, &st) || access(fn2, R_OK)) {
920 
921       WARNF("Unable to access '%s'", fn2);
922       continue;
923 
924     }
925 
926     ++done;
927 
928     if (!S_ISREG(st.st_mode) || !st.st_size) { continue; }
929 
930     if ((fn3 = strrchr(fn2, '/'))) {
931 
932       ++fn3;
933 
934     } else {
935 
936       fn3 = fn2;
937 
938     }
939 
940     if (st.st_size > MAX_FILE && !be_quiet && !quiet_mode) {
941 
942       WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", fn2,
943             stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size),
944             stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE));
945 
946     }
947 
948     if (!collect_coverage) {
949 
950       snprintf(outfile, sizeof(outfile), "%s/%s", out_file, fn3);
951 
952     }
953 
954     if (read_file(fn2)) {
955 
956       if (wait_for_gdb) {
957 
958         fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
959         fprintf(stderr, "exec: kill -CONT %d\n", getpid());
960         kill(0, SIGSTOP);
961 
962       }
963 
964       showmap_run_target_forkserver(fsrv, in_data, in_len);
965       ck_free(in_data);
966 
967       if (child_crashed && debug) { WARNF("crashed: %s", fn2); }
968 
969       if (collect_coverage)
970         analyze_results(fsrv);
971       else
972         tcnt = write_results_to_file(fsrv, outfile);
973 
974     }
975 
976   }
977 
978   return done;
979 
980 }
981 
982 /* Show banner. */
983 
show_banner(void)984 static void show_banner(void) {
985 
986   SAYF(cCYA "afl-showmap" VERSION cRST " by Michal Zalewski\n");
987 
988 }
989 
990 /* Display usage hints. */
991 
usage(u8 * argv0)992 static void usage(u8 *argv0) {
993 
994   show_banner();
995 
996   SAYF(
997       "\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
998 
999       "Required parameters:\n"
1000       "  -o file    - file to write the trace data to\n\n"
1001 
1002       "Execution control settings:\n"
1003       "  -t msec    - timeout for each run (default: 1000ms)\n"
1004       "  -m megs    - memory limit for child process (default: none)\n"
1005 #if defined(__linux__) && defined(__aarch64__)
1006       "  -A         - use binary-only instrumentation (ARM CoreSight mode)\n"
1007 #endif
1008       "  -O         - use binary-only instrumentation (FRIDA mode)\n"
1009 #if defined(__linux__)
1010       "  -Q         - use binary-only instrumentation (QEMU mode)\n"
1011       "  -U         - use Unicorn-based instrumentation (Unicorn mode)\n"
1012       "  -W         - use qemu-based instrumentation with Wine (Wine mode)\n"
1013       "               (Not necessary, here for consistency with other afl-* "
1014       "tools)\n"
1015       "  -X         - use Nyx mode\n"
1016 #endif
1017       "\n"
1018       "Other settings:\n"
1019       "  -i dir     - process all files below this directory, must be combined "
1020       "with -o.\n"
1021       "               With -C, -o is a file, without -C it must be a "
1022       "directory\n"
1023       "               and each bitmap will be written there individually.\n"
1024       "  -I filelist - alternatively to -i, -I is a list of files\n"
1025       "  -C         - collect coverage, writes all edges to -o and gives a "
1026       "summary\n"
1027       "               Must be combined with -i.\n"
1028       "  -q         - sink program's output and don't show messages\n"
1029       "  -e         - show edge coverage only, ignore hit counts\n"
1030       "  -r         - show real tuple values instead of AFL filter values\n"
1031       "  -s         - do not classify the map\n"
1032       "  -c         - allow core dumps\n\n"
1033 
1034       "This tool displays raw tuple data captured by AFL instrumentation.\n"
1035       "For additional help, consult %s/README.md.\n\n"
1036 
1037       "If you use -i/-I mode, then custom mutator post_process send send "
1038       "functionality\n"
1039       "is supported.\n\n"
1040 
1041       "Environment variables used:\n"
1042       "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
1043       "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing "
1044       "inputs\n"
1045       "AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n"
1046       "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as "
1047       "crash\n"
1048       "AFL_DEBUG: enable extra developer output\n"
1049       "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
1050       "startup (in milliseconds)\n"
1051       "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, "
1052       "etc.\n"
1053       "                 (default: SIGKILL)\n"
1054       "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on "
1055       "termination\n"
1056       "                             (default: SIGTERM). If unset and "
1057       "AFL_KILL_SIGNAL is\n"
1058       "                             set, that value will be used.\n"
1059       "AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
1060       "size the\n"
1061       "              target was compiled for\n"
1062       "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
1063       "AFL_PRINT_FILENAMES: Print the queue entry currently processed will to "
1064       "stdout\n"
1065       "AFL_QUIET: do not print extra informational output\n"
1066       "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n",
1067       argv0, doc_path);
1068 
1069   exit(1);
1070 
1071 }
1072 
1073 /* Main entry point */
1074 
main(int argc,char ** argv_orig,char ** envp)1075 int main(int argc, char **argv_orig, char **envp) {
1076 
1077   // TODO: u64 mem_limit = MEM_LIMIT;                  /* Memory limit (MB) */
1078 
1079   s32  opt, i;
1080   bool mem_limit_given = false, timeout_given = false, unicorn_mode = false,
1081        use_wine = false;
1082   char **use_argv;
1083 
1084   char **argv = argv_cpy_dup(argc, argv_orig);
1085 
1086   afl_forkserver_t fsrv_var = {0};
1087   if (getenv("AFL_DEBUG")) { debug = true; }
1088   if (get_afl_env("AFL_PRINT_FILENAMES")) { print_filenames = true; }
1089 
1090   fsrv = &fsrv_var;
1091   afl_fsrv_init(fsrv);
1092   map_size = get_map_size();
1093   fsrv->map_size = map_size;
1094 
1095   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
1096 
1097   if (getenv("AFL_QUIET") != NULL) { be_quiet = true; }
1098 
1099   while ((opt = getopt(argc, argv, "+i:I:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) {
1100 
1101     switch (opt) {
1102 
1103       case 's':
1104         no_classify = true;
1105         break;
1106 
1107       case 'C':
1108         collect_coverage = true;
1109         quiet_mode = true;
1110         break;
1111 
1112       case 'i':
1113         if (in_dir) { FATAL("Multiple -i options not supported"); }
1114         in_dir = optarg;
1115         break;
1116 
1117       case 'I':
1118         if (in_filelist) { FATAL("Multiple -I options not supported"); }
1119         in_filelist = optarg;
1120         break;
1121 
1122       case 'o':
1123 
1124         if (out_file) { FATAL("Multiple -o options not supported"); }
1125         out_file = optarg;
1126         break;
1127 
1128       case 'm': {
1129 
1130         u8 suffix = 'M';
1131 
1132         if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
1133         mem_limit_given = true;
1134 
1135         if (!optarg) { FATAL("Wrong usage of -m"); }
1136 
1137         if (!strcmp(optarg, "none")) {
1138 
1139           fsrv->mem_limit = 0;
1140           break;
1141 
1142         }
1143 
1144         if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
1145             optarg[0] == '-') {
1146 
1147           FATAL("Bad syntax used for -m");
1148 
1149         }
1150 
1151         switch (suffix) {
1152 
1153           case 'T':
1154             fsrv->mem_limit *= 1024 * 1024;
1155             break;
1156           case 'G':
1157             fsrv->mem_limit *= 1024;
1158             break;
1159           case 'k':
1160             fsrv->mem_limit /= 1024;
1161             break;
1162           case 'M':
1163             break;
1164 
1165           default:
1166             FATAL("Unsupported suffix or bad syntax for -m");
1167 
1168         }
1169 
1170         if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); }
1171 
1172         if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) {
1173 
1174           FATAL("Value of -m out of range on 32-bit systems");
1175 
1176         }
1177 
1178       }
1179 
1180       break;
1181 
1182       case 'f':  // only in here to avoid a compiler warning for use_stdin
1183 
1184         FATAL("Option -f is not supported in afl-showmap");
1185         // currently not reached:
1186         fsrv->use_stdin = 0;
1187         fsrv->out_file = strdup(optarg);
1188 
1189         break;
1190 
1191       case 't':
1192 
1193         if (timeout_given) { FATAL("Multiple -t options not supported"); }
1194         timeout_given = true;
1195 
1196         if (!optarg) { FATAL("Wrong usage of -t"); }
1197 
1198         if (strcmp(optarg, "none")) {
1199 
1200           fsrv->exec_tmout = atoi(optarg);
1201 
1202           if (fsrv->exec_tmout < 20 || optarg[0] == '-') {
1203 
1204             FATAL("Dangerously low value of -t");
1205 
1206           }
1207 
1208         } else {
1209 
1210           // The forkserver code does not have a way to completely
1211           // disable the timeout, so we'll use a very, very long
1212           // timeout instead.
1213           WARNF(
1214               "Setting an execution timeout of 120 seconds ('none' is not "
1215               "allowed).");
1216           fsrv->exec_tmout = 120 * 1000;
1217 
1218         }
1219 
1220         break;
1221 
1222       case 'e':
1223 
1224         if (edges_only) { FATAL("Multiple -e options not supported"); }
1225         if (raw_instr_output) { FATAL("-e and -r are mutually exclusive"); }
1226         edges_only = true;
1227         break;
1228 
1229       case 'q':
1230 
1231         quiet_mode = true;
1232         break;
1233 
1234       case 'Z':
1235 
1236         /* This is an undocumented option to write data in the syntax expected
1237            by afl-cmin. Nobody else should have any use for this. */
1238 
1239         cmin_mode = true;
1240         quiet_mode = true;
1241         break;
1242 
1243       case 'H':
1244         /* Another afl-cmin specific feature. */
1245         at_file = optarg;
1246         break;
1247 
1248       case 'O':                                               /* FRIDA mode */
1249 
1250         if (fsrv->frida_mode) { FATAL("Multiple -O options not supported"); }
1251 
1252         fsrv->frida_mode = true;
1253         setenv("AFL_FRIDA_INST_SEED", "1", 1);
1254 
1255         break;
1256 
1257       /* FIXME: We want to use -P for consistency, but it is already unsed for
1258        * undocumenetd feature "Another afl-cmin specific feature." */
1259       case 'A':                                           /* CoreSight mode */
1260 
1261 #if !defined(__aarch64__) || !defined(__linux__)
1262         FATAL("-A option is not supported on this platform");
1263 #endif
1264 
1265         if (fsrv->cs_mode) { FATAL("Multiple -A options not supported"); }
1266 
1267         fsrv->cs_mode = true;
1268         break;
1269 
1270       case 'Q':
1271 
1272         if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); }
1273 
1274         fsrv->qemu_mode = true;
1275         break;
1276 
1277       case 'U':
1278 
1279         if (unicorn_mode) { FATAL("Multiple -U options not supported"); }
1280 
1281         unicorn_mode = true;
1282         break;
1283 
1284       case 'W':                                           /* Wine+QEMU mode */
1285 
1286         if (use_wine) { FATAL("Multiple -W options not supported"); }
1287         fsrv->qemu_mode = true;
1288         use_wine = true;
1289 
1290         break;
1291 
1292       case 'Y':  // fallthrough
1293 #ifdef __linux__
1294       case 'X':                                                 /* NYX mode */
1295 
1296         if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); }
1297 
1298         fsrv->nyx_mode = 1;
1299         fsrv->nyx_parent = true;
1300         fsrv->nyx_standalone = true;
1301 
1302         break;
1303 #else
1304       case 'X':
1305         FATAL("Nyx mode is only availabe on linux...");
1306         break;
1307 #endif
1308 
1309       case 'b':
1310 
1311         /* Secret undocumented mode. Writes output in raw binary format
1312            similar to that dumped by afl-fuzz in <out_dir/queue/fuzz_bitmap. */
1313 
1314         binary_mode = true;
1315         break;
1316 
1317       case 'c':
1318 
1319         if (keep_cores) { FATAL("Multiple -c options not supported"); }
1320         keep_cores = true;
1321         break;
1322 
1323       case 'r':
1324 
1325         if (raw_instr_output) { FATAL("Multiple -r options not supported"); }
1326         if (edges_only) { FATAL("-e and -r are mutually exclusive"); }
1327         raw_instr_output = true;
1328         break;
1329 
1330       case 'h':
1331         usage(argv[0]);
1332         return -1;
1333         break;
1334 
1335       default:
1336         usage(argv[0]);
1337 
1338     }
1339 
1340   }
1341 
1342   if (optind == argc || !out_file) { usage(argv[0]); }
1343 
1344   if (in_dir && in_filelist) { FATAL("you can only specify either -i or -I"); }
1345 
1346   if (in_dir || in_filelist) {
1347 
1348     if (!out_file && !collect_coverage)
1349       FATAL("for -i/-I you need to specify either -C and/or -o");
1350 
1351   }
1352 
1353   if (fsrv->qemu_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
1354   if (unicorn_mode && !mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
1355 
1356   check_environment_vars(envp);
1357 
1358   if (getenv("AFL_NO_FORKSRV")) {             /* if set, use the fauxserver */
1359     fsrv->use_fauxsrv = true;
1360 
1361   }
1362 
1363   if (getenv("AFL_DEBUG")) {
1364 
1365     DEBUGF("");
1366     for (i = 0; i < argc; i++)
1367       SAYF(" %s", argv[i]);
1368     SAYF("\n");
1369 
1370   }
1371 
1372   //  if (afl->shmem_testcase_mode) { setup_testcase_shmem(afl); }
1373 
1374   setenv("AFL_NO_AUTODICT", "1", 1);
1375 
1376   /* initialize cmplog_mode */
1377   shm.cmplog_mode = 0;
1378   setup_signal_handlers();
1379 
1380   set_up_environment(fsrv, argv);
1381 
1382 #ifdef __linux__
1383   if (!fsrv->nyx_mode) {
1384 
1385     fsrv->target_path = find_binary(argv[optind]);
1386 
1387   } else {
1388 
1389     fsrv->target_path = ck_strdup(argv[optind]);
1390 
1391   }
1392 
1393 #else
1394   fsrv->target_path = find_binary(argv[optind]);
1395 #endif
1396 
1397   fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
1398 
1399   if (!quiet_mode) {
1400 
1401     show_banner();
1402     ACTF("Executing '%s'...", fsrv->target_path);
1403 
1404   }
1405 
1406   if (in_dir || in_filelist) {
1407 
1408     /* If we don't have a file name chosen yet, use a safe default. */
1409     u8 *use_dir = ".";
1410 
1411     if (access(use_dir, R_OK | W_OK | X_OK)) {
1412 
1413       use_dir = get_afl_env("TMPDIR");
1414       if (!use_dir) { use_dir = "/tmp"; }
1415 
1416     }
1417 
1418     stdin_file = at_file ? strdup(at_file)
1419                          : (char *)alloc_printf("%s/.afl-showmap-temp-%u",
1420                                                 use_dir, (u32)getpid());
1421     unlink(stdin_file);
1422 
1423     // If @@ are in the target args, replace them and also set use_stdin=false.
1424     detect_file_args(argv + optind, stdin_file, &fsrv->use_stdin);
1425 
1426     fsrv->dev_null_fd = open("/dev/null", O_RDWR);
1427     if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
1428 
1429     fsrv->out_file = stdin_file;
1430     fsrv->out_fd =
1431         open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
1432     if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", stdin_file); }
1433 
1434   } else {
1435 
1436     // If @@ are in the target args, replace them and also set use_stdin=false.
1437     detect_file_args(argv + optind, at_file, &fsrv->use_stdin);
1438 
1439   }
1440 
1441   if (fsrv->qemu_mode) {
1442 
1443     if (use_wine) {
1444 
1445       use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
1446                                argv + optind);
1447 
1448     } else {
1449 
1450       use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
1451                                argv + optind);
1452 
1453     }
1454 
1455   } else if (fsrv->cs_mode) {
1456 
1457     use_argv =
1458         get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind);
1459 
1460 #ifdef __linux__
1461 
1462   } else if (fsrv->nyx_mode) {
1463 
1464     use_argv = ck_alloc(sizeof(char *) * (1));
1465     use_argv[0] = argv[0];
1466 
1467     fsrv->nyx_id = 0;
1468 
1469     u8 *libnyx_binary = find_afl_binary(use_argv[0], "libnyx.so");
1470     fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary);
1471     if (fsrv->nyx_handlers == NULL) {
1472 
1473       FATAL("failed to initialize libnyx.so...");
1474 
1475     }
1476 
1477     fsrv->nyx_use_tmp_workdir = true;
1478     fsrv->nyx_bind_cpu_id = 0;
1479 #endif
1480 
1481   } else {
1482 
1483     use_argv = argv + optind;
1484 
1485   }
1486 
1487   afl = calloc(1, sizeof(afl_state_t));
1488 
1489   if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
1490 
1491     s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
1492     if (forksrv_init_tmout < 1) {
1493 
1494       FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
1495 
1496     }
1497 
1498     fsrv->init_tmout = (u32)forksrv_init_tmout;
1499 
1500   }
1501 
1502   if (getenv("AFL_CRASH_EXITCODE")) {
1503 
1504     long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
1505     if ((!exitcode && (errno == EINVAL || errno == ERANGE)) ||
1506         exitcode < -127 || exitcode > 128) {
1507 
1508       FATAL("Invalid crash exitcode, expected -127 to 128, but got %s",
1509             getenv("AFL_CRASH_EXITCODE"));
1510 
1511     }
1512 
1513     fsrv->uses_crash_exitcode = true;
1514     // WEXITSTATUS is 8 bit unsigned
1515     fsrv->crash_exitcode = (u8)exitcode;
1516 
1517   }
1518 
1519 #ifdef __linux__
1520   if (!fsrv->nyx_mode && (in_dir || in_filelist)) {
1521 
1522     (void)check_binary_signatures(fsrv->target_path);
1523 
1524   }
1525 
1526 #else
1527   if (in_dir) { (void)check_binary_signatures(fsrv->target_path); }
1528 #endif
1529 
1530   shm_fuzz = ck_alloc(sizeof(sharedmem_t));
1531 
1532   /* initialize cmplog_mode */
1533   shm_fuzz->cmplog_mode = 0;
1534   u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
1535   shm_fuzz->shmemfuzz_mode = true;
1536   if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
1537 #ifdef USEMMAP
1538   setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
1539 #else
1540   u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
1541   setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
1542   ck_free(shm_str);
1543 #endif
1544   fsrv->support_shmem_fuzz = true;
1545   fsrv->shmem_fuzz_len = (u32 *)map;
1546   fsrv->shmem_fuzz = map + sizeof(u32);
1547 
1548   configure_afl_kill_signals(fsrv, NULL, NULL,
1549                              (fsrv->qemu_mode || unicorn_mode
1550 #ifdef __linux__
1551                               || fsrv->nyx_mode
1552 #endif
1553                               )
1554                                  ? SIGKILL
1555                                  : SIGTERM);
1556 
1557   if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) {
1558 
1559     u32 save_be_quiet = be_quiet;
1560     be_quiet = !debug;
1561     if (map_size > 4194304) {
1562 
1563       fsrv->map_size = map_size;
1564 
1565     } else {
1566 
1567       fsrv->map_size = 4194304;  // dummy temporary value
1568 
1569     }
1570 
1571     u32 new_map_size =
1572         afl_fsrv_get_mapsize(fsrv, use_argv, &stop_soon,
1573                              (get_afl_env("AFL_DEBUG_CHILD") ||
1574                               get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
1575                                  ? 1
1576                                  : 0);
1577     be_quiet = save_be_quiet;
1578 
1579     if (new_map_size) {
1580 
1581       // only reinitialize when it makes sense
1582       if (map_size < new_map_size ||
1583           (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) {
1584 
1585         if (!be_quiet)
1586           ACTF("Acquired new map size for target: %u bytes\n", new_map_size);
1587 
1588         afl_shm_deinit(&shm);
1589         afl_fsrv_kill(fsrv);
1590         fsrv->map_size = new_map_size;
1591         fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0);
1592 
1593       }
1594 
1595       map_size = new_map_size;
1596 
1597     }
1598 
1599     fsrv->map_size = map_size;
1600 
1601   } else {
1602 
1603     afl_fsrv_start(fsrv, use_argv, &stop_soon,
1604                    (get_afl_env("AFL_DEBUG_CHILD") ||
1605                     get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
1606                        ? 1
1607                        : 0);
1608 
1609   }
1610 
1611   if (in_dir || in_filelist) {
1612 
1613     afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
1614     if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
1615     afl->afl_env.afl_custom_mutator_library =
1616         getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
1617     afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE");
1618     setup_custom_mutators(afl);
1619 
1620   } else {
1621 
1622     if (getenv("AFL_CUSTOM_MUTATOR_LIBRARY") || getenv("AFL_PYTHON_MODULE")) {
1623 
1624       WARNF(
1625           "Custom mutator environment detected, this is only supported in "
1626           "-i/-I mode!\n");
1627 
1628     }
1629 
1630   }
1631 
1632   if (in_dir || in_filelist) {
1633 
1634     DIR *dir_in, *dir_out = NULL;
1635     u8  *dn = NULL;
1636 
1637     if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
1638 
1639     if (in_filelist) {
1640 
1641       if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
1642 
1643     } else {
1644 
1645       // if a queue subdirectory exists switch to that
1646       dn = alloc_printf("%s/queue", in_dir);
1647 
1648       if ((dir_in = opendir(dn)) != NULL) {
1649 
1650         closedir(dir_in);
1651         in_dir = dn;
1652 
1653       } else {
1654 
1655         ck_free(dn);
1656 
1657       }
1658 
1659       if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir);
1660 
1661     }
1662 
1663     if (!collect_coverage) {
1664 
1665       if (!(dir_out = opendir(out_file))) {
1666 
1667         if (mkdir(out_file, 0700)) {
1668 
1669           PFATAL("cannot create output directory %s", out_file);
1670 
1671         }
1672 
1673       }
1674 
1675     } else {
1676 
1677       if ((coverage_map = (u8 *)malloc(map_size + 64)) == NULL)
1678         FATAL("coult not grab memory");
1679       edges_only = false;
1680       raw_instr_output = true;
1681 
1682     }
1683 
1684     atexit(at_exit_handler);
1685 
1686     if (get_afl_env("AFL_DEBUG")) {
1687 
1688       int j = optind;
1689       DEBUGF("%s:", fsrv->target_path);
1690       while (argv[j] != NULL) {
1691 
1692         SAYF(" \"%s\"", argv[j++]);
1693 
1694       }
1695 
1696       SAYF("\n");
1697 
1698     }
1699 
1700     map_size = fsrv->map_size;
1701 
1702     if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
1703       shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
1704 
1705     if (in_dir) {
1706 
1707       if (execute_testcases(in_dir) == 0) {
1708 
1709         FATAL("could not read input testcases from %s", in_dir);
1710 
1711       }
1712 
1713     } else {
1714 
1715       if (execute_testcases_filelist(in_filelist) == 0) {
1716 
1717         FATAL("could not read input testcases from %s", in_filelist);
1718 
1719       }
1720 
1721     }
1722 
1723     if (!quiet_mode) { OKF("Processed %llu input files.", fsrv->total_execs); }
1724 
1725     if (dir_out) { closedir(dir_out); }
1726 
1727     if (collect_coverage) {
1728 
1729       memcpy(fsrv->trace_bits, coverage_map, map_size);
1730       tcnt = write_results_to_file(fsrv, out_file);
1731 
1732     }
1733 
1734   } else {
1735 
1736     if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
1737       shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
1738 
1739 #ifdef __linux__
1740     if (!fsrv->nyx_mode) {
1741 
1742 #endif
1743       showmap_run_target(fsrv, use_argv);
1744 #ifdef __linux__
1745 
1746     } else {
1747 
1748       showmap_run_target_nyx_mode(fsrv);
1749 
1750     }
1751 
1752 #endif
1753     tcnt = write_results_to_file(fsrv, out_file);
1754     if (!quiet_mode) {
1755 
1756       OKF("Hash of coverage map: %llx",
1757           hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST));
1758 
1759     }
1760 
1761   }
1762 
1763   if (!quiet_mode || collect_coverage) {
1764 
1765     if (!tcnt && !have_coverage) { FATAL("No instrumentation detected" cRST); }
1766     OKF("Captured %u tuples (map size %u, highest value %u, total values %llu) "
1767         "in '%s'." cRST,
1768         tcnt, fsrv->real_map_size, highest, total, out_file);
1769     if (collect_coverage)
1770       OKF("A coverage of %u edges were achieved out of %u existing (%.02f%%) "
1771           "with %llu input files.",
1772           tcnt, map_size, ((float)tcnt * 100) / (float)map_size,
1773           fsrv->total_execs);
1774 
1775   }
1776 
1777   if (stdin_file) {
1778 
1779     unlink(stdin_file);
1780     ck_free(stdin_file);
1781     stdin_file = NULL;
1782 
1783   }
1784 
1785   remove_shm = 0;
1786   afl_shm_deinit(&shm);
1787   if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
1788 
1789   u32 ret;
1790 
1791   if (cmin_mode && !!getenv("AFL_CMIN_CRASHES_ONLY")) {
1792 
1793     ret = fsrv->last_run_timed_out;
1794 
1795   } else {
1796 
1797     ret = child_crashed * 2 + fsrv->last_run_timed_out;
1798 
1799   }
1800 
1801   if (fsrv->target_path) { ck_free(fsrv->target_path); }
1802 
1803   afl_fsrv_deinit(fsrv);
1804 
1805   if (stdin_file) { ck_free(stdin_file); }
1806   if (collect_coverage) { free(coverage_map); }
1807 
1808   argv_cpy_free(argv);
1809   if (fsrv->qemu_mode) { free(use_argv[2]); }
1810 
1811   exit(ret);
1812 
1813 }
1814 
1815