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