1 /*
2 american fuzzy lop++ - forkserver code
3 --------------------------------------
4
5 Originally written by Michal Zalewski
6
7 Forkserver design by Jann Horn <jannhorn@googlemail.com>
8
9 Now maintained by Marc Heuse <mh@mh-sec.de>,
10 Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
11 Andrea Fioraldi <andreafioraldi@gmail.com> and
12 Dominik Maier <mail@dmnk.co>
13
14
15 Copyright 2016, 2017 Google Inc. All rights reserved.
16 Copyright 2019-2022 AFLplusplus Project. All rights reserved.
17
18 Licensed under the Apache License, Version 2.0 (the "License");
19 you may not use this file except in compliance with the License.
20 You may obtain a copy of the License at:
21
22 https://www.apache.org/licenses/LICENSE-2.0
23
24 Shared code that implements a forkserver. This is used by the fuzzer
25 as well the other components like afl-tmin.
26
27 */
28
29 #include "config.h"
30 #include "types.h"
31 #include "debug.h"
32 #include "common.h"
33 #include "list.h"
34 #include "forkserver.h"
35 #include "hash.h"
36
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42 #include <errno.h>
43 #include <signal.h>
44 #include <fcntl.h>
45 #include <limits.h>
46 #include <sys/time.h>
47 #include <sys/wait.h>
48 #include <sys/resource.h>
49 #include <sys/select.h>
50 #include <sys/stat.h>
51
52 /**
53 * The correct fds for reading and writing pipes
54 */
55
56 /* Describe integer as memory size. */
57
58 static list_t fsrv_list = {.element_prealloc_count = 0};
59
fsrv_exec_child(afl_forkserver_t * fsrv,char ** argv)60 static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
61
62 if (fsrv->qemu_mode || fsrv->cs_mode) {
63
64 setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0);
65
66 }
67
68 execv(fsrv->target_path, argv);
69
70 WARNF("Execv failed in forkserver.");
71
72 }
73
74 /* Initializes the struct */
75
afl_fsrv_init(afl_forkserver_t * fsrv)76 void afl_fsrv_init(afl_forkserver_t *fsrv) {
77
78 #ifdef __linux__
79 fsrv->nyx_handlers = NULL;
80 fsrv->out_dir_path = NULL;
81 fsrv->nyx_mode = 0;
82 fsrv->nyx_parent = false;
83 fsrv->nyx_standalone = false;
84 fsrv->nyx_runner = NULL;
85 fsrv->nyx_id = 0xFFFFFFFF;
86 fsrv->nyx_bind_cpu_id = 0xFFFFFFFF;
87 #endif
88
89 // this structure needs default so we initialize it if this was not done
90 // already
91 fsrv->out_fd = -1;
92 fsrv->out_dir_fd = -1;
93 fsrv->dev_null_fd = -1;
94 fsrv->dev_urandom_fd = -1;
95
96 /* Settings */
97 fsrv->use_stdin = true;
98 fsrv->no_unlink = false;
99 fsrv->exec_tmout = EXEC_TIMEOUT;
100 fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
101 fsrv->mem_limit = MEM_LIMIT;
102 fsrv->out_file = NULL;
103 fsrv->kill_signal = SIGKILL;
104
105 /* exec related stuff */
106 fsrv->child_pid = -1;
107 fsrv->map_size = get_map_size();
108 fsrv->real_map_size = fsrv->map_size;
109 fsrv->use_fauxsrv = false;
110 fsrv->last_run_timed_out = false;
111 fsrv->debug = false;
112 fsrv->uses_crash_exitcode = false;
113 fsrv->uses_asan = false;
114
115 fsrv->init_child_func = fsrv_exec_child;
116 list_append(&fsrv_list, fsrv);
117
118 }
119
120 /* Initialize a new forkserver instance, duplicating "global" settings */
afl_fsrv_init_dup(afl_forkserver_t * fsrv_to,afl_forkserver_t * from)121 void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
122
123 fsrv_to->use_stdin = from->use_stdin;
124 fsrv_to->dev_null_fd = from->dev_null_fd;
125 fsrv_to->exec_tmout = from->exec_tmout;
126 fsrv_to->init_tmout = from->init_tmout;
127 fsrv_to->mem_limit = from->mem_limit;
128 fsrv_to->map_size = from->map_size;
129 fsrv_to->real_map_size = from->real_map_size;
130 fsrv_to->support_shmem_fuzz = from->support_shmem_fuzz;
131 fsrv_to->out_file = from->out_file;
132 fsrv_to->dev_urandom_fd = from->dev_urandom_fd;
133 fsrv_to->out_fd = from->out_fd; // not sure this is a good idea
134 fsrv_to->no_unlink = from->no_unlink;
135 fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode;
136 fsrv_to->crash_exitcode = from->crash_exitcode;
137 fsrv_to->kill_signal = from->kill_signal;
138 fsrv_to->debug = from->debug;
139
140 // These are forkserver specific.
141 fsrv_to->out_dir_fd = -1;
142 fsrv_to->child_pid = -1;
143 fsrv_to->use_fauxsrv = 0;
144 fsrv_to->last_run_timed_out = 0;
145
146 fsrv_to->init_child_func = from->init_child_func;
147 // Note: do not copy ->add_extra_func or ->persistent_record*
148
149 list_append(&fsrv_list, fsrv_to);
150
151 }
152
153 /* Wrapper for select() and read(), reading a 32 bit var.
154 Returns the time passed to read.
155 If the wait times out, returns timeout_ms + 1;
156 Returns 0 if an error occurred (fd closed, signal, ...); */
157 static u32 __attribute__((hot))
read_s32_timed(s32 fd,s32 * buf,u32 timeout_ms,volatile u8 * stop_soon_p)158 read_s32_timed(s32 fd, s32 *buf, u32 timeout_ms, volatile u8 *stop_soon_p) {
159
160 fd_set readfds;
161 FD_ZERO(&readfds);
162 FD_SET(fd, &readfds);
163 struct timeval timeout;
164 int sret;
165 ssize_t len_read;
166
167 timeout.tv_sec = (timeout_ms / 1000);
168 timeout.tv_usec = (timeout_ms % 1000) * 1000;
169 #if !defined(__linux__)
170 u32 read_start = get_cur_time_us();
171 #endif
172
173 /* set exceptfds as well to return when a child exited/closed the pipe. */
174 restart_select:
175 sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
176
177 if (likely(sret > 0)) {
178
179 restart_read:
180 if (*stop_soon_p) {
181
182 // Early return - the user wants to quit.
183 return 0;
184
185 }
186
187 len_read = read(fd, (u8 *)buf, 4);
188
189 if (likely(len_read == 4)) { // for speed we put this first
190
191 #if defined(__linux__)
192 u32 exec_ms = MIN(
193 timeout_ms,
194 ((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
195 #else
196 u32 exec_ms = MIN(timeout_ms, (get_cur_time_us() - read_start) / 1000);
197 #endif
198
199 // ensure to report 1 ms has passed (0 is an error)
200 return exec_ms > 0 ? exec_ms : 1;
201
202 } else if (unlikely(len_read == -1 && errno == EINTR)) {
203
204 goto restart_read;
205
206 } else if (unlikely(len_read < 4)) {
207
208 return 0;
209
210 }
211
212 } else if (unlikely(!sret)) {
213
214 *buf = -1;
215 return timeout_ms + 1;
216
217 } else if (unlikely(sret < 0)) {
218
219 if (likely(errno == EINTR)) goto restart_select;
220
221 *buf = -1;
222 return 0;
223
224 }
225
226 return 0; // not reached
227
228 }
229
230 /* Internal forkserver for non_instrumented_mode=1 and non-forkserver mode runs.
231 It execvs for each fork, forwarding exit codes and child pids to afl. */
232
afl_fauxsrv_execv(afl_forkserver_t * fsrv,char ** argv)233 static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
234
235 unsigned char tmp[4] = {0, 0, 0, 0};
236 pid_t child_pid;
237
238 if (!be_quiet) { ACTF("Using Fauxserver:"); }
239
240 /* Phone home and tell the parent that we're OK. If parent isn't there,
241 assume we're not running in forkserver mode and just execute program. */
242
243 if (write(FORKSRV_FD + 1, tmp, 4) != 4) {
244
245 abort(); // TODO: Abort?
246
247 }
248
249 void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
250
251 while (1) {
252
253 uint32_t was_killed;
254 int status;
255
256 /* Wait for parent by reading from the pipe. Exit if read fails. */
257
258 if (read(FORKSRV_FD, &was_killed, 4) != 4) { exit(0); }
259
260 /* Create a clone of our process. */
261
262 child_pid = fork();
263
264 if (child_pid < 0) { PFATAL("Fork failed"); }
265
266 /* In child process: close fds, resume execution. */
267
268 if (!child_pid) { // New child
269
270 close(fsrv->out_dir_fd);
271 close(fsrv->dev_null_fd);
272 close(fsrv->dev_urandom_fd);
273
274 if (fsrv->plot_file != NULL) {
275
276 fclose(fsrv->plot_file);
277 fsrv->plot_file = NULL;
278
279 }
280
281 // enable terminating on sigpipe in the childs
282 struct sigaction sa;
283 memset((char *)&sa, 0, sizeof(sa));
284 sa.sa_handler = SIG_DFL;
285 sigaction(SIGPIPE, &sa, NULL);
286
287 signal(SIGCHLD, old_sigchld_handler);
288
289 // FORKSRV_FD is for communication with AFL, we don't need it in the
290 // child
291 close(FORKSRV_FD);
292 close(FORKSRV_FD + 1);
293
294 // finally: exec...
295 execv(fsrv->target_path, argv);
296
297 /* Use a distinctive bitmap signature to tell the parent about execv()
298 falling through. */
299
300 *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
301
302 WARNF("Execv failed in fauxserver.");
303 break;
304
305 }
306
307 /* In parent process: write PID to AFL. */
308
309 if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) { exit(0); }
310
311 /* after child exited, get and relay exit status to parent through waitpid.
312 */
313
314 if (waitpid(child_pid, &status, 0) < 0) {
315
316 // Zombie Child could not be collected. Scary!
317 WARNF("Fauxserver could not determine child's exit code. ");
318
319 }
320
321 /* Relay wait status to AFL pipe, then loop back. */
322
323 if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(1); }
324
325 }
326
327 }
328
329 /* Report on the error received via the forkserver controller and exit */
report_error_and_exit(int error)330 static void report_error_and_exit(int error) {
331
332 switch (error) {
333
334 case FS_ERROR_MAP_SIZE:
335 FATAL(
336 "AFL_MAP_SIZE is not set and fuzzing target reports that the "
337 "required size is very large. Solution: Run the fuzzing target "
338 "stand-alone with the environment variable AFL_DEBUG=1 set and set "
339 "the value for __afl_final_loc in the AFL_MAP_SIZE environment "
340 "variable for afl-fuzz.");
341 break;
342 case FS_ERROR_MAP_ADDR:
343 FATAL(
344 "the fuzzing target reports that hardcoded map address might be the "
345 "reason the mmap of the shared memory failed. Solution: recompile "
346 "the target with either afl-clang-lto and do not set "
347 "AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.");
348 break;
349 case FS_ERROR_SHM_OPEN:
350 FATAL("the fuzzing target reports that the shm_open() call failed.");
351 break;
352 case FS_ERROR_SHMAT:
353 FATAL("the fuzzing target reports that the shmat() call failed.");
354 break;
355 case FS_ERROR_MMAP:
356 FATAL(
357 "the fuzzing target reports that the mmap() call to the shared "
358 "memory failed.");
359 break;
360 case FS_ERROR_OLD_CMPLOG:
361 FATAL(
362 "the -c cmplog target was instrumented with an too old afl++ "
363 "version, you need to recompile it.");
364 break;
365 case FS_ERROR_OLD_CMPLOG_QEMU:
366 FATAL(
367 "The AFL++ QEMU/FRIDA loaders are from an older version, for -c you "
368 "need to recompile it.\n");
369 break;
370 default:
371 FATAL("unknown error code %d from fuzzing target!", error);
372
373 }
374
375 }
376
377 /* Spins up fork server. The idea is explained here:
378
379 https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html
380
381 In essence, the instrumentation allows us to skip execve(), and just keep
382 cloning a stopped child. So, we just execute once, and then send commands
383 through a pipe. The other part of this logic is in afl-as.h / llvm_mode */
384
afl_fsrv_start(afl_forkserver_t * fsrv,char ** argv,volatile u8 * stop_soon_p,u8 debug_child_output)385 void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
386 volatile u8 *stop_soon_p, u8 debug_child_output) {
387
388 int st_pipe[2], ctl_pipe[2];
389 s32 status;
390 s32 rlen;
391 char *ignore_autodict = getenv("AFL_NO_AUTODICT");
392
393 #ifdef __linux__
394 if (unlikely(fsrv->nyx_mode)) {
395
396 if (fsrv->nyx_runner != NULL) { return; }
397
398 if (!be_quiet) { ACTF("Spinning up the NYX backend..."); }
399
400 if (fsrv->out_dir_path == NULL) { FATAL("Nyx workdir path not found..."); }
401
402 char *x = alloc_printf("%s/workdir", fsrv->out_dir_path);
403
404 if (fsrv->nyx_id == 0xFFFFFFFF) { FATAL("Nyx ID is not set..."); }
405
406 if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) {
407
408 FATAL("Nyx CPU ID is not set...");
409
410 }
411
412 if (fsrv->nyx_standalone) {
413
414 fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
415 fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
416
417 } else {
418
419 if (fsrv->nyx_parent) {
420
421 fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_parent(
422 fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
423
424 } else {
425
426 fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child(
427 fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id);
428
429 }
430
431 }
432
433 ck_free(x);
434
435 if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
436
437 u32 tmp_map_size =
438 fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);
439 fsrv->real_map_size = tmp_map_size;
440 fsrv->map_size = (((tmp_map_size + 63) >> 6) << 6);
441 if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); }
442
443 fsrv->trace_bits =
444 fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner);
445
446 fsrv->nyx_handlers->nyx_option_set_reload_mode(
447 fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL);
448 fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
449
450 fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
451 fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
452
453 fsrv->nyx_aux_string = malloc(0x1000);
454 memset(fsrv->nyx_aux_string, 0, 0x1000);
455
456 /* dry run */
457 fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4);
458 switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) {
459
460 case Abort:
461 fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
462 FATAL("Error: Nyx abort occured...");
463 break;
464 case IoError:
465 FATAL("Error: QEMU-Nyx has died...");
466 break;
467 case Error:
468 fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
469 FATAL("Error: Nyx runtime error has occured...");
470 break;
471 default:
472 break;
473
474 }
475
476 /* autodict in Nyx mode */
477 if (!ignore_autodict) {
478
479 x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path);
480 int nyx_autodict_fd = open(x, O_RDONLY);
481 ck_free(x);
482
483 if (nyx_autodict_fd >= 0) {
484
485 struct stat st;
486 if (fstat(nyx_autodict_fd, &st) >= 0) {
487
488 u32 f_len = st.st_size;
489 u8 *dict = ck_alloc(f_len);
490 if (dict == NULL) {
491
492 FATAL("Could not allocate %u bytes of autodictionary memory",
493 f_len);
494
495 }
496
497 u32 offset = 0, count = 0;
498 u32 len = f_len;
499
500 while (len != 0) {
501
502 rlen = read(nyx_autodict_fd, dict + offset, len);
503 if (rlen > 0) {
504
505 len -= rlen;
506 offset += rlen;
507
508 } else {
509
510 FATAL(
511 "Reading autodictionary fail at position %u with %u bytes "
512 "left.",
513 offset, len);
514
515 }
516
517 }
518
519 offset = 0;
520 while (offset < (u32)f_len &&
521 (u8)dict[offset] + offset < (u32)f_len) {
522
523 fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
524 (u8)dict[offset]);
525 offset += (1 + dict[offset]);
526 count++;
527
528 }
529
530 if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
531 ck_free(dict);
532
533 }
534
535 close(nyx_autodict_fd);
536
537 }
538
539 }
540
541 return;
542
543 }
544
545 #endif
546
547 if (!be_quiet) { ACTF("Spinning up the fork server..."); }
548
549 #ifdef AFL_PERSISTENT_RECORD
550 if (unlikely(fsrv->persistent_record)) {
551
552 fsrv->persistent_record_data =
553 (u8 **)ck_alloc(fsrv->persistent_record * sizeof(u8 *));
554 fsrv->persistent_record_len =
555 (u32 *)ck_alloc(fsrv->persistent_record * sizeof(u32));
556
557 if (!fsrv->persistent_record_data || !fsrv->persistent_record_len) {
558
559 FATAL("Unable to allocate memory for persistent replay.");
560
561 }
562
563 }
564
565 #endif
566
567 if (fsrv->use_fauxsrv) {
568
569 /* TODO: Come up with some nice way to initialize this all */
570
571 if (fsrv->init_child_func != fsrv_exec_child) {
572
573 FATAL("Different forkserver not compatible with fauxserver");
574
575 }
576
577 if (!be_quiet) { ACTF("Using AFL++ faux forkserver..."); }
578 fsrv->init_child_func = afl_fauxsrv_execv;
579
580 }
581
582 if (pipe(st_pipe) || pipe(ctl_pipe)) { PFATAL("pipe() failed"); }
583
584 fsrv->last_run_timed_out = 0;
585 fsrv->fsrv_pid = fork();
586
587 if (fsrv->fsrv_pid < 0) { PFATAL("fork() failed"); }
588
589 if (!fsrv->fsrv_pid) {
590
591 /* CHILD PROCESS */
592
593 // enable terminating on sigpipe in the childs
594 struct sigaction sa;
595 memset((char *)&sa, 0, sizeof(sa));
596 sa.sa_handler = SIG_DFL;
597 sigaction(SIGPIPE, &sa, NULL);
598
599 struct rlimit r;
600
601 if (!fsrv->cmplog_binary) {
602
603 unsetenv(CMPLOG_SHM_ENV_VAR); // we do not want that in non-cmplog fsrv
604
605 }
606
607 /* Umpf. On OpenBSD, the default fd limit for root users is set to
608 soft 128. Let's try to fix that... */
609 if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < FORKSRV_FD + 2) {
610
611 r.rlim_cur = FORKSRV_FD + 2;
612 setrlimit(RLIMIT_NOFILE, &r); /* Ignore errors */
613
614 }
615
616 if (fsrv->mem_limit) {
617
618 r.rlim_max = r.rlim_cur = ((rlim_t)fsrv->mem_limit) << 20;
619
620 #ifdef RLIMIT_AS
621 setrlimit(RLIMIT_AS, &r); /* Ignore errors */
622 #else
623 /* This takes care of OpenBSD, which doesn't have RLIMIT_AS, but
624 according to reliable sources, RLIMIT_DATA covers anonymous
625 maps - so we should be getting good protection against OOM bugs. */
626
627 setrlimit(RLIMIT_DATA, &r); /* Ignore errors */
628 #endif /* ^RLIMIT_AS */
629
630 }
631
632 /* Dumping cores is slow and can lead to anomalies if SIGKILL is delivered
633 before the dump is complete. */
634
635 if (!fsrv->debug) {
636
637 r.rlim_max = r.rlim_cur = 0;
638 setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
639
640 }
641
642 /* Isolate the process and configure standard descriptors. If out_file is
643 specified, stdin is /dev/null; otherwise, out_fd is cloned instead. */
644
645 setsid();
646
647 if (!(debug_child_output)) {
648
649 dup2(fsrv->dev_null_fd, 1);
650 dup2(fsrv->dev_null_fd, 2);
651
652 }
653
654 if (!fsrv->use_stdin) {
655
656 dup2(fsrv->dev_null_fd, 0);
657
658 } else {
659
660 dup2(fsrv->out_fd, 0);
661 close(fsrv->out_fd);
662
663 }
664
665 /* Set up control and status pipes, close the unneeded original fds. */
666
667 if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) { PFATAL("dup2() failed"); }
668 if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) { PFATAL("dup2() failed"); }
669
670 close(ctl_pipe[0]);
671 close(ctl_pipe[1]);
672 close(st_pipe[0]);
673 close(st_pipe[1]);
674
675 close(fsrv->out_dir_fd);
676 close(fsrv->dev_null_fd);
677 close(fsrv->dev_urandom_fd);
678
679 if (fsrv->plot_file != NULL) {
680
681 fclose(fsrv->plot_file);
682 fsrv->plot_file = NULL;
683
684 }
685
686 /* This should improve performance a bit, since it stops the linker from
687 doing extra work post-fork(). */
688
689 if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 1); }
690
691 /* Set sane defaults for ASAN if nothing else is specified. */
692
693 if (!getenv("ASAN_OPTIONS"))
694 setenv("ASAN_OPTIONS",
695 "abort_on_error=1:"
696 "detect_leaks=0:"
697 "malloc_context_size=0:"
698 "symbolize=0:"
699 "allocator_may_return_null=1:"
700 "detect_odr_violation=0:"
701 "handle_segv=0:"
702 "handle_sigbus=0:"
703 "handle_abort=0:"
704 "handle_sigfpe=0:"
705 "handle_sigill=0",
706 1);
707
708 /* Set sane defaults for UBSAN if nothing else is specified. */
709
710 if (!getenv("UBSAN_OPTIONS"))
711 setenv("UBSAN_OPTIONS",
712 "halt_on_error=1:"
713 "abort_on_error=1:"
714 "malloc_context_size=0:"
715 "allocator_may_return_null=1:"
716 "symbolize=0:"
717 "handle_segv=0:"
718 "handle_sigbus=0:"
719 "handle_abort=0:"
720 "handle_sigfpe=0:"
721 "handle_sigill=0",
722 1);
723
724 /* Envs for QASan */
725 setenv("QASAN_MAX_CALL_STACK", "0", 0);
726 setenv("QASAN_SYMBOLIZE", "0", 0);
727
728 /* MSAN is tricky, because it doesn't support abort_on_error=1 at this
729 point. So, we do this in a very hacky way. */
730
731 if (!getenv("MSAN_OPTIONS"))
732 setenv("MSAN_OPTIONS",
733 "exit_code=" STRINGIFY(MSAN_ERROR) ":"
734 "symbolize=0:"
735 "abort_on_error=1:"
736 "malloc_context_size=0:"
737 "allocator_may_return_null=1:"
738 "msan_track_origins=0:"
739 "handle_segv=0:"
740 "handle_sigbus=0:"
741 "handle_abort=0:"
742 "handle_sigfpe=0:"
743 "handle_sigill=0",
744 1);
745
746 /* LSAN, too, does not support abort_on_error=1. */
747
748 if (!getenv("LSAN_OPTIONS"))
749 setenv("LSAN_OPTIONS",
750 "exitcode=" STRINGIFY(LSAN_ERROR) ":"
751 "fast_unwind_on_malloc=0:"
752 "symbolize=0:"
753 "print_suppressions=0",
754 1);
755
756 fsrv->init_child_func(fsrv, argv);
757
758 /* Use a distinctive bitmap signature to tell the parent about execv()
759 falling through. */
760
761 *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
762 FATAL("Error: execv to target failed\n");
763
764 }
765
766 /* PARENT PROCESS */
767
768 char pid_buf[16];
769 sprintf(pid_buf, "%d", fsrv->fsrv_pid);
770 if (fsrv->cmplog_binary)
771 setenv("__AFL_TARGET_PID2", pid_buf, 1);
772 else
773 setenv("__AFL_TARGET_PID1", pid_buf, 1);
774
775 /* Close the unneeded endpoints. */
776
777 close(ctl_pipe[0]);
778 close(st_pipe[1]);
779
780 fsrv->fsrv_ctl_fd = ctl_pipe[1];
781 fsrv->fsrv_st_fd = st_pipe[0];
782
783 /* Wait for the fork server to come up, but don't wait too long. */
784
785 rlen = 0;
786 if (fsrv->init_tmout) {
787
788 u32 time_ms = read_s32_timed(fsrv->fsrv_st_fd, &status, fsrv->init_tmout,
789 stop_soon_p);
790
791 if (!time_ms) {
792
793 s32 tmp_pid = fsrv->fsrv_pid;
794 if (tmp_pid > 0) {
795
796 kill(tmp_pid, fsrv->kill_signal);
797 fsrv->fsrv_pid = -1;
798
799 }
800
801 } else if (time_ms > fsrv->init_tmout) {
802
803 fsrv->last_run_timed_out = 1;
804 s32 tmp_pid = fsrv->fsrv_pid;
805 if (tmp_pid > 0) {
806
807 kill(tmp_pid, fsrv->kill_signal);
808 fsrv->fsrv_pid = -1;
809
810 }
811
812 } else {
813
814 rlen = 4;
815
816 }
817
818 } else {
819
820 rlen = read(fsrv->fsrv_st_fd, &status, 4);
821
822 }
823
824 /* If we have a four-byte "hello" message from the server, we're all set.
825 Otherwise, try to figure out what went wrong. */
826
827 if (rlen == 4) {
828
829 if (!be_quiet) { OKF("All right - fork server is up."); }
830
831 if (getenv("AFL_DEBUG")) {
832
833 ACTF("Extended forkserver functions received (%08x).", status);
834
835 }
836
837 if ((status & FS_OPT_ERROR) == FS_OPT_ERROR)
838 report_error_and_exit(FS_OPT_GET_ERROR(status));
839
840 if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
841
842 // workaround for recent afl++ versions
843 if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
844 status = (status & 0xf0ffffff);
845
846 if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) {
847
848 if (fsrv->qemu_mode || fsrv->frida_mode) {
849
850 report_error_and_exit(FS_ERROR_OLD_CMPLOG_QEMU);
851
852 } else {
853
854 report_error_and_exit(FS_ERROR_OLD_CMPLOG);
855
856 }
857
858 }
859
860 if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
861
862 fsrv->snapshot = 1;
863 if (!be_quiet) { ACTF("Using SNAPSHOT feature."); }
864
865 }
866
867 if ((status & FS_OPT_SHDMEM_FUZZ) == FS_OPT_SHDMEM_FUZZ) {
868
869 if (fsrv->support_shmem_fuzz) {
870
871 fsrv->use_shmem_fuzz = 1;
872 if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); }
873
874 if ((status & FS_OPT_AUTODICT) == 0 || ignore_autodict) {
875
876 u32 send_status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
877 if (write(fsrv->fsrv_ctl_fd, &send_status, 4) != 4) {
878
879 FATAL("Writing to forkserver failed.");
880
881 }
882
883 }
884
885 } else {
886
887 FATAL(
888 "Target requested sharedmem fuzzing, but we failed to enable "
889 "it.");
890
891 }
892
893 }
894
895 if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
896
897 u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
898
899 if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; }
900
901 fsrv->real_map_size = tmp_map_size;
902
903 if (tmp_map_size % 64) {
904
905 tmp_map_size = (((tmp_map_size + 63) >> 6) << 6);
906
907 }
908
909 if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); }
910 if (tmp_map_size > fsrv->map_size) {
911
912 FATAL(
913 "Target's coverage map size of %u is larger than the one this "
914 "afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
915 " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
916 "afl-fuzz",
917 tmp_map_size, fsrv->map_size, tmp_map_size);
918
919 }
920
921 fsrv->map_size = tmp_map_size;
922
923 }
924
925 if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) {
926
927 if (!ignore_autodict) {
928
929 if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) {
930
931 // this is not afl-fuzz - or it is cmplog - we deny and return
932 if (fsrv->use_shmem_fuzz) {
933
934 status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ);
935
936 } else {
937
938 status = (FS_OPT_ENABLED);
939
940 }
941
942 if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
943
944 FATAL("Writing to forkserver failed.");
945
946 }
947
948 return;
949
950 }
951
952 if (!be_quiet) { ACTF("Using AUTODICT feature."); }
953
954 if (fsrv->use_shmem_fuzz) {
955
956 status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ);
957
958 } else {
959
960 status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
961
962 }
963
964 if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
965
966 FATAL("Writing to forkserver failed.");
967
968 }
969
970 if (read(fsrv->fsrv_st_fd, &status, 4) != 4) {
971
972 FATAL("Reading from forkserver failed.");
973
974 }
975
976 if (status < 2 || (u32)status > 0xffffff) {
977
978 FATAL("Dictionary has an illegal size: %d", status);
979
980 }
981
982 u32 offset = 0, count = 0;
983 u32 len = status;
984 u8 *dict = ck_alloc(len);
985 if (dict == NULL) {
986
987 FATAL("Could not allocate %u bytes of autodictionary memory", len);
988
989 }
990
991 while (len != 0) {
992
993 rlen = read(fsrv->fsrv_st_fd, dict + offset, len);
994 if (rlen > 0) {
995
996 len -= rlen;
997 offset += rlen;
998
999 } else {
1000
1001 FATAL(
1002 "Reading autodictionary fail at position %u with %u bytes "
1003 "left.",
1004 offset, len);
1005
1006 }
1007
1008 }
1009
1010 offset = 0;
1011 while (offset < (u32)status &&
1012 (u8)dict[offset] + offset < (u32)status) {
1013
1014 fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1,
1015 (u8)dict[offset]);
1016 offset += (1 + dict[offset]);
1017 count++;
1018
1019 }
1020
1021 if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
1022 ck_free(dict);
1023
1024 }
1025
1026 }
1027
1028 }
1029
1030 return;
1031
1032 }
1033
1034 if (fsrv->last_run_timed_out) {
1035
1036 FATAL(
1037 "Timeout while initializing fork server (setting "
1038 "AFL_FORKSRV_INIT_TMOUT may help)");
1039
1040 }
1041
1042 if (waitpid(fsrv->fsrv_pid, &status, 0) <= 0) { PFATAL("waitpid() failed"); }
1043
1044 if (WIFSIGNALED(status)) {
1045
1046 if (fsrv->mem_limit && fsrv->mem_limit < 500 && fsrv->uses_asan) {
1047
1048 SAYF("\n" cLRD "[-] " cRST
1049 "Whoops, the target binary crashed suddenly, "
1050 "before receiving any input\n"
1051 " from the fuzzer! Since it seems to be built with ASAN and you "
1052 "have a\n"
1053 " restrictive memory limit configured, this is expected; please "
1054 "run with '-m 0'.\n");
1055
1056 } else if (!fsrv->mem_limit) {
1057
1058 SAYF("\n" cLRD "[-] " cRST
1059 "Whoops, the target binary crashed suddenly, "
1060 "before receiving any input\n"
1061 " from the fuzzer! You can try the following:\n\n"
1062
1063 " - The target binary crashes because necessary runtime "
1064 "conditions it needs\n"
1065 " are not met. Try to:\n"
1066 " 1. Run again with AFL_DEBUG=1 set and check the output of "
1067 "the target\n"
1068 " binary for clues.\n"
1069 " 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
1070 "analyze the\n"
1071 " generated core dump.\n\n"
1072
1073 " - Possibly the target requires a huge coverage map and has "
1074 "CTORS.\n"
1075 " Retry with setting AFL_MAP_SIZE=10000000.\n\n"
1076
1077 MSG_FORK_ON_APPLE
1078
1079 " - Less likely, there is a horrible bug in the fuzzer. If other "
1080 "options\n"
1081 " fail, poke <afl-users@googlegroups.com> for troubleshooting "
1082 "tips.\n");
1083
1084 } else {
1085
1086 u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
1087
1088 SAYF("\n" cLRD "[-] " cRST
1089 "Whoops, the target binary crashed suddenly, "
1090 "before receiving any input\n"
1091 " from the fuzzer! You can try the following:\n\n"
1092
1093 " - The target binary crashes because necessary runtime "
1094 "conditions it needs\n"
1095 " are not met. Try to:\n"
1096 " 1. Run again with AFL_DEBUG=1 set and check the output of "
1097 "the target\n"
1098 " binary for clues.\n"
1099 " 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
1100 "analyze the\n"
1101 " generated core dump.\n\n"
1102
1103 " - The current memory limit (%s) is too restrictive, causing "
1104 "the\n"
1105 " target to hit an OOM condition in the dynamic linker. Try "
1106 "bumping up\n"
1107 " the limit with the -m setting in the command line. A simple "
1108 "way confirm\n"
1109 " this diagnosis would be:\n\n"
1110
1111 MSG_ULIMIT_USAGE
1112 " /path/to/fuzzed_app )\n\n"
1113
1114 " Tip: you can use https://jwilk.net/software/recidivm to\n"
1115 " estimate the required amount of virtual memory for the "
1116 "binary.\n\n"
1117
1118 MSG_FORK_ON_APPLE
1119
1120 " - Possibly the target requires a huge coverage map and has "
1121 "CTORS.\n"
1122 " Retry with setting AFL_MAP_SIZE=10000000.\n\n"
1123
1124 " - Less likely, there is a horrible bug in the fuzzer. If other "
1125 "options\n"
1126 " fail, poke <afl-users@googlegroups.com> for troubleshooting "
1127 "tips.\n",
1128 stringify_mem_size(val_buf, sizeof(val_buf), fsrv->mem_limit << 20),
1129 fsrv->mem_limit - 1);
1130
1131 }
1132
1133 FATAL("Fork server crashed with signal %d", WTERMSIG(status));
1134
1135 }
1136
1137 if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) {
1138
1139 FATAL("Unable to execute target application ('%s')", argv[0]);
1140
1141 }
1142
1143 if (fsrv->mem_limit && fsrv->mem_limit < 500 && fsrv->uses_asan) {
1144
1145 SAYF("\n" cLRD "[-] " cRST
1146 "Hmm, looks like the target binary terminated "
1147 "before we could complete a\n"
1148 " handshake with the injected code. Since it seems to be built "
1149 "with ASAN and\n"
1150 " you have a restrictive memory limit configured, this is "
1151 "expected; please\n"
1152 " run with '-m 0'.\n");
1153
1154 } else if (!fsrv->mem_limit) {
1155
1156 SAYF("\n" cLRD "[-] " cRST
1157 "Hmm, looks like the target binary terminated before we could complete"
1158 " a\n"
1159 "handshake with the injected code. You can try the following:\n\n"
1160
1161 " - The target binary crashes because necessary runtime conditions "
1162 "it needs\n"
1163 " are not met. Try to:\n"
1164 " 1. Run again with AFL_DEBUG=1 set and check the output of the "
1165 "target\n"
1166 " binary for clues.\n"
1167 " 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
1168 "analyze the\n"
1169 " generated core dump.\n\n"
1170
1171 " - Possibly the target requires a huge coverage map and has "
1172 "CTORS.\n"
1173 " Retry with setting AFL_MAP_SIZE=10000000.\n\n"
1174
1175 "Otherwise there is a horrible bug in the fuzzer.\n"
1176 "Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
1177
1178 } else {
1179
1180 u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
1181
1182 SAYF(
1183 "\n" cLRD "[-] " cRST
1184 "Hmm, looks like the target binary terminated "
1185 "before we could complete a\n"
1186 " handshake with the injected code. You can try the following:\n\n"
1187
1188 "%s"
1189
1190 " - The target binary crashes because necessary runtime conditions "
1191 "it needs\n"
1192 " are not met. Try to:\n"
1193 " 1. Run again with AFL_DEBUG=1 set and check the output of the "
1194 "target\n"
1195 " binary for clues.\n"
1196 " 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
1197 "analyze the\n"
1198 " generated core dump.\n\n"
1199
1200 " - Possibly the target requires a huge coverage map and has "
1201 "CTORS.\n"
1202 " Retry with setting AFL_MAP_SIZE=10000000.\n\n"
1203
1204 " - The current memory limit (%s) is too restrictive, causing an "
1205 "OOM\n"
1206 " fault in the dynamic linker. This can be fixed with the -m "
1207 "option. A\n"
1208 " simple way to confirm the diagnosis may be:\n\n"
1209
1210 MSG_ULIMIT_USAGE
1211 " /path/to/fuzzed_app )\n\n"
1212
1213 " Tip: you can use https://jwilk.net/software/recidivm to\n"
1214 " estimate the required amount of virtual memory for the "
1215 "binary.\n\n"
1216
1217 " - The target was compiled with afl-clang-lto and a constructor "
1218 "was\n"
1219 " instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve "
1220 "your \n"
1221 " problem\n\n"
1222
1223 " - Less likely, there is a horrible bug in the fuzzer. If other "
1224 "options\n"
1225 " fail, poke <afl-users@googlegroups.com> for troubleshooting "
1226 "tips.\n",
1227 getenv(DEFER_ENV_VAR)
1228 ? " - You are using deferred forkserver, but __AFL_INIT() is "
1229 "never\n"
1230 " reached before the program terminates.\n\n"
1231 : "",
1232 stringify_int(val_buf, sizeof(val_buf), fsrv->mem_limit << 20),
1233 fsrv->mem_limit - 1);
1234
1235 }
1236
1237 FATAL("Fork server handshake failed");
1238
1239 }
1240
1241 /* Stop the forkserver and child */
1242
afl_fsrv_kill(afl_forkserver_t * fsrv)1243 void afl_fsrv_kill(afl_forkserver_t *fsrv) {
1244
1245 if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
1246 if (fsrv->fsrv_pid > 0) {
1247
1248 kill(fsrv->fsrv_pid, fsrv->kill_signal);
1249 if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
1250
1251 }
1252
1253 close(fsrv->fsrv_ctl_fd);
1254 close(fsrv->fsrv_st_fd);
1255 fsrv->fsrv_pid = -1;
1256 fsrv->child_pid = -1;
1257
1258 #ifdef __linux__
1259 if (fsrv->nyx_mode) {
1260
1261 free(fsrv->nyx_aux_string);
1262 fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
1263
1264 }
1265
1266 #endif
1267
1268 }
1269
1270 /* Get the map size from the target forkserver */
1271
afl_fsrv_get_mapsize(afl_forkserver_t * fsrv,char ** argv,volatile u8 * stop_soon_p,u8 debug_child_output)1272 u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv,
1273 volatile u8 *stop_soon_p, u8 debug_child_output) {
1274
1275 afl_fsrv_start(fsrv, argv, stop_soon_p, debug_child_output);
1276 return fsrv->map_size;
1277
1278 }
1279
1280 /* Delete the current testcase and write the buf to the testcase file */
1281
1282 void __attribute__((hot))
afl_fsrv_write_to_testcase(afl_forkserver_t * fsrv,u8 * buf,size_t len)1283 afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
1284
1285 #ifdef __linux__
1286 if (unlikely(fsrv->nyx_mode)) {
1287
1288 fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, buf, len);
1289 return;
1290
1291 }
1292
1293 #endif
1294
1295 #ifdef AFL_PERSISTENT_RECORD
1296 if (unlikely(fsrv->persistent_record)) {
1297
1298 fsrv->persistent_record_len[fsrv->persistent_record_idx] = len;
1299 fsrv->persistent_record_data[fsrv->persistent_record_idx] = afl_realloc(
1300 (void **)&fsrv->persistent_record_data[fsrv->persistent_record_idx],
1301 len);
1302
1303 if (unlikely(!fsrv->persistent_record_data[fsrv->persistent_record_idx])) {
1304
1305 FATAL("allocating replay memory failed.");
1306
1307 }
1308
1309 memcpy(fsrv->persistent_record_data[fsrv->persistent_record_idx], buf, len);
1310
1311 if (unlikely(++fsrv->persistent_record_idx >= fsrv->persistent_record)) {
1312
1313 fsrv->persistent_record_idx = 0;
1314
1315 }
1316
1317 }
1318
1319 #endif
1320
1321 if (likely(fsrv->use_shmem_fuzz)) {
1322
1323 if (unlikely(len > MAX_FILE)) len = MAX_FILE;
1324
1325 *fsrv->shmem_fuzz_len = len;
1326 memcpy(fsrv->shmem_fuzz, buf, len);
1327 #ifdef _DEBUG
1328 if (getenv("AFL_DEBUG")) {
1329
1330 fprintf(stderr, "FS crc: %016llx len: %u\n",
1331 hash64(fsrv->shmem_fuzz, *fsrv->shmem_fuzz_len, HASH_CONST),
1332 *fsrv->shmem_fuzz_len);
1333 fprintf(stderr, "SHM :");
1334 for (u32 i = 0; i < *fsrv->shmem_fuzz_len; i++)
1335 fprintf(stderr, "%02x", fsrv->shmem_fuzz[i]);
1336 fprintf(stderr, "\nORIG:");
1337 for (u32 i = 0; i < *fsrv->shmem_fuzz_len; i++)
1338 fprintf(stderr, "%02x", buf[i]);
1339 fprintf(stderr, "\n");
1340
1341 }
1342
1343 #endif
1344
1345 } else {
1346
1347 s32 fd = fsrv->out_fd;
1348
1349 if (!fsrv->use_stdin && fsrv->out_file) {
1350
1351 if (unlikely(fsrv->no_unlink)) {
1352
1353 fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC,
1354 DEFAULT_PERMISSION);
1355
1356 } else {
1357
1358 unlink(fsrv->out_file); /* Ignore errors. */
1359 fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL,
1360 DEFAULT_PERMISSION);
1361
1362 }
1363
1364 if (fd < 0) { PFATAL("Unable to create '%s'", fsrv->out_file); }
1365
1366 } else if (unlikely(fd <= 0)) {
1367
1368 // We should have a (non-stdin) fd at this point, else we got a problem.
1369 FATAL(
1370 "Nowhere to write output to (neither out_fd nor out_file set (fd is "
1371 "%d))",
1372 fd);
1373
1374 } else {
1375
1376 lseek(fd, 0, SEEK_SET);
1377
1378 }
1379
1380 // fprintf(stderr, "WRITE %d %u\n", fd, len);
1381 ck_write(fd, buf, len, fsrv->out_file);
1382
1383 if (fsrv->use_stdin) {
1384
1385 if (ftruncate(fd, len)) { PFATAL("ftruncate() failed"); }
1386 lseek(fd, 0, SEEK_SET);
1387
1388 } else {
1389
1390 close(fd);
1391
1392 }
1393
1394 }
1395
1396 }
1397
1398 /* Execute target application, monitoring for timeouts. Return status
1399 information. The called program will update afl->fsrv->trace_bits. */
1400
1401 fsrv_run_result_t __attribute__((hot))
afl_fsrv_run_target(afl_forkserver_t * fsrv,u32 timeout,volatile u8 * stop_soon_p)1402 afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
1403 volatile u8 *stop_soon_p) {
1404
1405 s32 res;
1406 u32 exec_ms;
1407 u32 write_value = fsrv->last_run_timed_out;
1408
1409 #ifdef __linux__
1410 if (fsrv->nyx_mode) {
1411
1412 static uint32_t last_timeout_value = 0;
1413
1414 if (last_timeout_value != timeout) {
1415
1416 fsrv->nyx_handlers->nyx_option_set_timeout(
1417 fsrv->nyx_runner, timeout / 1000, (timeout % 1000) * 1000);
1418 fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
1419 last_timeout_value = timeout;
1420
1421 }
1422
1423 enum NyxReturnValue ret_val =
1424 fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner);
1425
1426 fsrv->total_execs++;
1427
1428 switch (ret_val) {
1429
1430 case Normal:
1431 return FSRV_RUN_OK;
1432 case Crash:
1433 case Asan:
1434 return FSRV_RUN_CRASH;
1435 case Timout:
1436 return FSRV_RUN_TMOUT;
1437 case InvalidWriteToPayload:
1438 /* ??? */
1439 FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing");
1440 break;
1441 case Abort:
1442 fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
1443 FATAL("Error: Nyx abort occured...");
1444 case IoError:
1445 if (*stop_soon_p) {
1446
1447 return 0;
1448
1449 } else {
1450
1451 FATAL("Error: QEMU-Nyx has died...");
1452
1453 }
1454
1455 break;
1456 case Error:
1457 FATAL("Error: Nyx runtime error has occured...");
1458 break;
1459
1460 }
1461
1462 return FSRV_RUN_OK;
1463
1464 }
1465
1466 #endif
1467 /* After this memset, fsrv->trace_bits[] are effectively volatile, so we
1468 must prevent any earlier operations from venturing into that
1469 territory. */
1470
1471 #ifdef __linux__
1472 if (!fsrv->nyx_mode) {
1473
1474 memset(fsrv->trace_bits, 0, fsrv->map_size);
1475 MEM_BARRIER();
1476
1477 }
1478
1479 #else
1480 memset(fsrv->trace_bits, 0, fsrv->map_size);
1481 MEM_BARRIER();
1482 #endif
1483
1484 /* we have the fork server (or faux server) up and running
1485 First, tell it if the previous run timed out. */
1486
1487 if ((res = write(fsrv->fsrv_ctl_fd, &write_value, 4)) != 4) {
1488
1489 if (*stop_soon_p) { return 0; }
1490 RPFATAL(res, "Unable to request new process from fork server (OOM?)");
1491
1492 }
1493
1494 fsrv->last_run_timed_out = 0;
1495
1496 if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
1497
1498 if (*stop_soon_p) { return 0; }
1499 RPFATAL(res, "Unable to request new process from fork server (OOM?)");
1500
1501 }
1502
1503 #ifdef AFL_PERSISTENT_RECORD
1504 // end of persistent loop?
1505 if (unlikely(fsrv->persistent_record &&
1506 fsrv->persistent_record_pid != fsrv->child_pid)) {
1507
1508 fsrv->persistent_record_pid = fsrv->child_pid;
1509 u32 idx, val;
1510 if (unlikely(!fsrv->persistent_record_idx))
1511 idx = fsrv->persistent_record - 1;
1512 else
1513 idx = fsrv->persistent_record_idx - 1;
1514 val = fsrv->persistent_record_len[idx];
1515 memset((void *)fsrv->persistent_record_len, 0,
1516 fsrv->persistent_record * sizeof(u32));
1517 fsrv->persistent_record_len[idx] = val;
1518
1519 }
1520
1521 #endif
1522
1523 if (fsrv->child_pid <= 0) {
1524
1525 if (*stop_soon_p) { return 0; }
1526
1527 if ((fsrv->child_pid & FS_OPT_ERROR) &&
1528 FS_OPT_GET_ERROR(fsrv->child_pid) == FS_ERROR_SHM_OPEN)
1529 FATAL(
1530 "Target reported shared memory access failed (perhaps increase "
1531 "shared memory available).");
1532
1533 FATAL("Fork server is misbehaving (OOM?)");
1534
1535 }
1536
1537 exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout,
1538 stop_soon_p);
1539
1540 if (exec_ms > timeout) {
1541
1542 /* If there was no response from forkserver after timeout seconds,
1543 we kill the child. The forkserver should inform us afterwards */
1544
1545 s32 tmp_pid = fsrv->child_pid;
1546 if (tmp_pid > 0) {
1547
1548 kill(tmp_pid, fsrv->kill_signal);
1549 fsrv->child_pid = -1;
1550
1551 }
1552
1553 fsrv->last_run_timed_out = 1;
1554 if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
1555
1556 }
1557
1558 if (!exec_ms) {
1559
1560 if (*stop_soon_p) { return 0; }
1561 SAYF("\n" cLRD "[-] " cRST
1562 "Unable to communicate with fork server. Some possible reasons:\n\n"
1563 " - You've run out of memory. Use -m to increase the the memory "
1564 "limit\n"
1565 " to something higher than %llu.\n"
1566 " - The binary or one of the libraries it uses manages to "
1567 "create\n"
1568 " threads before the forkserver initializes.\n"
1569 " - The binary, at least in some circumstances, exits in a way "
1570 "that\n"
1571 " also kills the parent process - raise() could be the "
1572 "culprit.\n"
1573 " - If using persistent mode with QEMU, "
1574 "AFL_QEMU_PERSISTENT_ADDR "
1575 "is\n"
1576 " probably not valid (hint: add the base address in case of "
1577 "PIE)"
1578 "\n\n"
1579 "If all else fails you can disable the fork server via "
1580 "AFL_NO_FORKSRV=1.\n",
1581 fsrv->mem_limit);
1582 RPFATAL(res, "Unable to communicate with fork server");
1583
1584 }
1585
1586 if (!WIFSTOPPED(fsrv->child_status)) { fsrv->child_pid = -1; }
1587
1588 fsrv->total_execs++;
1589
1590 /* Any subsequent operations on fsrv->trace_bits must not be moved by the
1591 compiler below this point. Past this location, fsrv->trace_bits[]
1592 behave very normally and do not have to be treated as volatile. */
1593
1594 MEM_BARRIER();
1595
1596 /* Report outcome to caller. */
1597
1598 /* Was the run unsuccessful? */
1599 if (unlikely(*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG)) {
1600
1601 return FSRV_RUN_ERROR;
1602
1603 }
1604
1605 /* Did we timeout? */
1606 if (unlikely(fsrv->last_run_timed_out)) {
1607
1608 fsrv->last_kill_signal = fsrv->kill_signal;
1609 return FSRV_RUN_TMOUT;
1610
1611 }
1612
1613 /* Did we crash?
1614 In a normal case, (abort) WIFSIGNALED(child_status) will be set.
1615 MSAN in uses_asan mode uses a special exit code as it doesn't support
1616 abort_on_error. On top, a user may specify a custom AFL_CRASH_EXITCODE.
1617 Handle all three cases here. */
1618
1619 if (unlikely(
1620 /* A normal crash/abort */
1621 (WIFSIGNALED(fsrv->child_status)) ||
1622 /* special handling for msan and lsan */
1623 (fsrv->uses_asan &&
1624 (WEXITSTATUS(fsrv->child_status) == MSAN_ERROR ||
1625 WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) ||
1626 /* the custom crash_exitcode was returned by the target */
1627 (fsrv->uses_crash_exitcode &&
1628 WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) {
1629
1630 #ifdef AFL_PERSISTENT_RECORD
1631 if (unlikely(fsrv->persistent_record)) {
1632
1633 char fn[PATH_MAX];
1634 u32 i, writecnt = 0;
1635 for (i = 0; i < fsrv->persistent_record; ++i) {
1636
1637 u32 entry = (i + fsrv->persistent_record_idx) % fsrv->persistent_record;
1638 u8 *data = fsrv->persistent_record_data[entry];
1639 u32 len = fsrv->persistent_record_len[entry];
1640 if (likely(len && data)) {
1641
1642 snprintf(fn, sizeof(fn), "%s/RECORD:%06u,cnt:%06u",
1643 fsrv->persistent_record_dir, fsrv->persistent_record_cnt,
1644 writecnt++);
1645 int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644);
1646 if (fd >= 0) {
1647
1648 ck_write(fd, data, len, fn);
1649 close(fd);
1650
1651 }
1652
1653 }
1654
1655 }
1656
1657 ++fsrv->persistent_record_cnt;
1658
1659 }
1660
1661 #endif
1662
1663 /* For a proper crash, set last_kill_signal to WTERMSIG, else set it to 0 */
1664 fsrv->last_kill_signal =
1665 WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0;
1666 return FSRV_RUN_CRASH;
1667
1668 }
1669
1670 /* success :) */
1671 return FSRV_RUN_OK;
1672
1673 }
1674
afl_fsrv_killall()1675 void afl_fsrv_killall() {
1676
1677 LIST_FOREACH(&fsrv_list, afl_forkserver_t, {
1678
1679 afl_fsrv_kill(el);
1680
1681 });
1682
1683 }
1684
afl_fsrv_deinit(afl_forkserver_t * fsrv)1685 void afl_fsrv_deinit(afl_forkserver_t *fsrv) {
1686
1687 afl_fsrv_kill(fsrv);
1688 list_remove(&fsrv_list, fsrv);
1689
1690 }
1691
1692