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