1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker american fuzzy lop++ - test case minimizer
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 Copyright 2016, 2017 Google Inc. All rights reserved.
15*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AFLplusplus Project. All rights reserved.
16*08b48e0bSAndroid Build Coastguard Worker
17*08b48e0bSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License");
18*08b48e0bSAndroid Build Coastguard Worker you may not use this file except in compliance with the License.
19*08b48e0bSAndroid Build Coastguard Worker You may obtain a copy of the License at:
20*08b48e0bSAndroid Build Coastguard Worker
21*08b48e0bSAndroid Build Coastguard Worker https://www.apache.org/licenses/LICENSE-2.0
22*08b48e0bSAndroid Build Coastguard Worker
23*08b48e0bSAndroid Build Coastguard Worker A simple test case minimizer that takes an input file and tries to remove
24*08b48e0bSAndroid Build Coastguard Worker as much data as possible while keeping the binary in a crashing state
25*08b48e0bSAndroid Build Coastguard Worker *or* producing consistent instrumentation output (the mode is auto-selected
26*08b48e0bSAndroid Build Coastguard Worker based on the initially observed behavior).
27*08b48e0bSAndroid Build Coastguard Worker
28*08b48e0bSAndroid Build Coastguard Worker */
29*08b48e0bSAndroid Build Coastguard Worker
30*08b48e0bSAndroid Build Coastguard Worker #define AFL_MAIN
31*08b48e0bSAndroid Build Coastguard Worker
32*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
33*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
34*08b48e0bSAndroid Build Coastguard Worker #include "debug.h"
35*08b48e0bSAndroid Build Coastguard Worker #include "alloc-inl.h"
36*08b48e0bSAndroid Build Coastguard Worker #include "hash.h"
37*08b48e0bSAndroid Build Coastguard Worker #include "forkserver.h"
38*08b48e0bSAndroid Build Coastguard Worker #include "sharedmem.h"
39*08b48e0bSAndroid Build Coastguard Worker #include "common.h"
40*08b48e0bSAndroid Build Coastguard Worker
41*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
42*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
43*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
44*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
45*08b48e0bSAndroid Build Coastguard Worker #include <time.h>
46*08b48e0bSAndroid Build Coastguard Worker #include <errno.h>
47*08b48e0bSAndroid Build Coastguard Worker #include <signal.h>
48*08b48e0bSAndroid Build Coastguard Worker #include <dirent.h>
49*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
50*08b48e0bSAndroid Build Coastguard Worker #include <limits.h>
51*08b48e0bSAndroid Build Coastguard Worker
52*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
53*08b48e0bSAndroid Build Coastguard Worker #include <sys/time.h>
54*08b48e0bSAndroid Build Coastguard Worker #ifndef USEMMAP
55*08b48e0bSAndroid Build Coastguard Worker #include <sys/shm.h>
56*08b48e0bSAndroid Build Coastguard Worker #endif
57*08b48e0bSAndroid Build Coastguard Worker #include <sys/stat.h>
58*08b48e0bSAndroid Build Coastguard Worker #include <sys/types.h>
59*08b48e0bSAndroid Build Coastguard Worker #include <sys/resource.h>
60*08b48e0bSAndroid Build Coastguard Worker
61*08b48e0bSAndroid Build Coastguard Worker static u8 *mask_bitmap; /* Mask for trace bits (-B) */
62*08b48e0bSAndroid Build Coastguard Worker
63*08b48e0bSAndroid Build Coastguard Worker static u8 *in_file, /* Minimizer input test case */
64*08b48e0bSAndroid Build Coastguard Worker *out_file, *output_file; /* Minimizer output file */
65*08b48e0bSAndroid Build Coastguard Worker
66*08b48e0bSAndroid Build Coastguard Worker static u8 *in_data; /* Input data for trimming */
67*08b48e0bSAndroid Build Coastguard Worker
68*08b48e0bSAndroid Build Coastguard Worker static u32 in_len, /* Input data length */
69*08b48e0bSAndroid Build Coastguard Worker missed_hangs, /* Misses due to hangs */
70*08b48e0bSAndroid Build Coastguard Worker missed_crashes, /* Misses due to crashes */
71*08b48e0bSAndroid Build Coastguard Worker missed_paths, /* Misses due to exec path diffs */
72*08b48e0bSAndroid Build Coastguard Worker map_size = MAP_SIZE;
73*08b48e0bSAndroid Build Coastguard Worker
74*08b48e0bSAndroid Build Coastguard Worker static u64 orig_cksum; /* Original checksum */
75*08b48e0bSAndroid Build Coastguard Worker
76*08b48e0bSAndroid Build Coastguard Worker static u8 crash_mode, /* Crash-centric mode? */
77*08b48e0bSAndroid Build Coastguard Worker hang_mode, /* Minimize as long as it hangs */
78*08b48e0bSAndroid Build Coastguard Worker exit_crash, /* Treat non-zero exit as crash? */
79*08b48e0bSAndroid Build Coastguard Worker edges_only, /* Ignore hit counts? */
80*08b48e0bSAndroid Build Coastguard Worker exact_mode, /* Require path match for crashes? */
81*08b48e0bSAndroid Build Coastguard Worker remove_out_file, /* remove out_file on exit? */
82*08b48e0bSAndroid Build Coastguard Worker remove_shm = 1, /* remove shmem on exit? */
83*08b48e0bSAndroid Build Coastguard Worker debug; /* debug mode */
84*08b48e0bSAndroid Build Coastguard Worker
85*08b48e0bSAndroid Build Coastguard Worker static volatile u8 stop_soon; /* Ctrl-C pressed? */
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard Worker static afl_forkserver_t *fsrv;
88*08b48e0bSAndroid Build Coastguard Worker static sharedmem_t shm;
89*08b48e0bSAndroid Build Coastguard Worker static sharedmem_t *shm_fuzz;
90*08b48e0bSAndroid Build Coastguard Worker
91*08b48e0bSAndroid Build Coastguard Worker /*
92*08b48e0bSAndroid Build Coastguard Worker * forkserver section
93*08b48e0bSAndroid Build Coastguard Worker */
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker /* Classify tuple counts. This is a slow & naive version, but good enough here.
96*08b48e0bSAndroid Build Coastguard Worker */
97*08b48e0bSAndroid Build Coastguard Worker
98*08b48e0bSAndroid Build Coastguard Worker static const u8 count_class_lookup[256] = {
99*08b48e0bSAndroid Build Coastguard Worker
100*08b48e0bSAndroid Build Coastguard Worker [0] = 0,
101*08b48e0bSAndroid Build Coastguard Worker [1] = 1,
102*08b48e0bSAndroid Build Coastguard Worker [2] = 2,
103*08b48e0bSAndroid Build Coastguard Worker [3] = 4,
104*08b48e0bSAndroid Build Coastguard Worker [4 ... 7] = 8,
105*08b48e0bSAndroid Build Coastguard Worker [8 ... 15] = 16,
106*08b48e0bSAndroid Build Coastguard Worker [16 ... 31] = 32,
107*08b48e0bSAndroid Build Coastguard Worker [32 ... 127] = 64,
108*08b48e0bSAndroid Build Coastguard Worker [128 ... 255] = 128
109*08b48e0bSAndroid Build Coastguard Worker
110*08b48e0bSAndroid Build Coastguard Worker };
111*08b48e0bSAndroid Build Coastguard Worker
kill_child()112*08b48e0bSAndroid Build Coastguard Worker static void kill_child() {
113*08b48e0bSAndroid Build Coastguard Worker
114*08b48e0bSAndroid Build Coastguard Worker if (fsrv->child_pid > 0) {
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker kill(fsrv->child_pid, fsrv->child_kill_signal);
117*08b48e0bSAndroid Build Coastguard Worker fsrv->child_pid = -1;
118*08b48e0bSAndroid Build Coastguard Worker
119*08b48e0bSAndroid Build Coastguard Worker }
120*08b48e0bSAndroid Build Coastguard Worker
121*08b48e0bSAndroid Build Coastguard Worker }
122*08b48e0bSAndroid Build Coastguard Worker
deinit_shmem(afl_forkserver_t * fsrv,sharedmem_t * shm_fuzz)123*08b48e0bSAndroid Build Coastguard Worker static sharedmem_t *deinit_shmem(afl_forkserver_t *fsrv,
124*08b48e0bSAndroid Build Coastguard Worker sharedmem_t *shm_fuzz) {
125*08b48e0bSAndroid Build Coastguard Worker
126*08b48e0bSAndroid Build Coastguard Worker afl_shm_deinit(shm_fuzz);
127*08b48e0bSAndroid Build Coastguard Worker fsrv->support_shmem_fuzz = 0;
128*08b48e0bSAndroid Build Coastguard Worker fsrv->shmem_fuzz_len = NULL;
129*08b48e0bSAndroid Build Coastguard Worker fsrv->shmem_fuzz = NULL;
130*08b48e0bSAndroid Build Coastguard Worker ck_free(shm_fuzz);
131*08b48e0bSAndroid Build Coastguard Worker return NULL;
132*08b48e0bSAndroid Build Coastguard Worker
133*08b48e0bSAndroid Build Coastguard Worker }
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker /* Apply mask to classified bitmap (if set). */
136*08b48e0bSAndroid Build Coastguard Worker
apply_mask(u32 * mem,u32 * mask)137*08b48e0bSAndroid Build Coastguard Worker static void apply_mask(u32 *mem, u32 *mask) {
138*08b48e0bSAndroid Build Coastguard Worker
139*08b48e0bSAndroid Build Coastguard Worker u32 i = (map_size >> 2);
140*08b48e0bSAndroid Build Coastguard Worker
141*08b48e0bSAndroid Build Coastguard Worker if (!mask) { return; }
142*08b48e0bSAndroid Build Coastguard Worker
143*08b48e0bSAndroid Build Coastguard Worker while (i--) {
144*08b48e0bSAndroid Build Coastguard Worker
145*08b48e0bSAndroid Build Coastguard Worker *mem &= ~*mask;
146*08b48e0bSAndroid Build Coastguard Worker mem++;
147*08b48e0bSAndroid Build Coastguard Worker mask++;
148*08b48e0bSAndroid Build Coastguard Worker
149*08b48e0bSAndroid Build Coastguard Worker }
150*08b48e0bSAndroid Build Coastguard Worker
151*08b48e0bSAndroid Build Coastguard Worker }
152*08b48e0bSAndroid Build Coastguard Worker
classify_counts(afl_forkserver_t * fsrv)153*08b48e0bSAndroid Build Coastguard Worker static void classify_counts(afl_forkserver_t *fsrv) {
154*08b48e0bSAndroid Build Coastguard Worker
155*08b48e0bSAndroid Build Coastguard Worker u8 *mem = fsrv->trace_bits;
156*08b48e0bSAndroid Build Coastguard Worker u32 i = map_size;
157*08b48e0bSAndroid Build Coastguard Worker
158*08b48e0bSAndroid Build Coastguard Worker if (edges_only) {
159*08b48e0bSAndroid Build Coastguard Worker
160*08b48e0bSAndroid Build Coastguard Worker while (i--) {
161*08b48e0bSAndroid Build Coastguard Worker
162*08b48e0bSAndroid Build Coastguard Worker if (*mem) { *mem = 1; }
163*08b48e0bSAndroid Build Coastguard Worker mem++;
164*08b48e0bSAndroid Build Coastguard Worker
165*08b48e0bSAndroid Build Coastguard Worker }
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker } else {
168*08b48e0bSAndroid Build Coastguard Worker
169*08b48e0bSAndroid Build Coastguard Worker while (i--) {
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker *mem = count_class_lookup[*mem];
172*08b48e0bSAndroid Build Coastguard Worker mem++;
173*08b48e0bSAndroid Build Coastguard Worker
174*08b48e0bSAndroid Build Coastguard Worker }
175*08b48e0bSAndroid Build Coastguard Worker
176*08b48e0bSAndroid Build Coastguard Worker }
177*08b48e0bSAndroid Build Coastguard Worker
178*08b48e0bSAndroid Build Coastguard Worker }
179*08b48e0bSAndroid Build Coastguard Worker
180*08b48e0bSAndroid Build Coastguard Worker /* See if any bytes are set in the bitmap. */
181*08b48e0bSAndroid Build Coastguard Worker
anything_set(afl_forkserver_t * fsrv)182*08b48e0bSAndroid Build Coastguard Worker static inline u8 anything_set(afl_forkserver_t *fsrv) {
183*08b48e0bSAndroid Build Coastguard Worker
184*08b48e0bSAndroid Build Coastguard Worker u32 *ptr = (u32 *)fsrv->trace_bits;
185*08b48e0bSAndroid Build Coastguard Worker u32 i = (map_size >> 2);
186*08b48e0bSAndroid Build Coastguard Worker
187*08b48e0bSAndroid Build Coastguard Worker while (i--) {
188*08b48e0bSAndroid Build Coastguard Worker
189*08b48e0bSAndroid Build Coastguard Worker if (*(ptr++)) { return 1; }
190*08b48e0bSAndroid Build Coastguard Worker
191*08b48e0bSAndroid Build Coastguard Worker }
192*08b48e0bSAndroid Build Coastguard Worker
193*08b48e0bSAndroid Build Coastguard Worker return 0;
194*08b48e0bSAndroid Build Coastguard Worker
195*08b48e0bSAndroid Build Coastguard Worker }
196*08b48e0bSAndroid Build Coastguard Worker
at_exit_handler(void)197*08b48e0bSAndroid Build Coastguard Worker static void at_exit_handler(void) {
198*08b48e0bSAndroid Build Coastguard Worker
199*08b48e0bSAndroid Build Coastguard Worker if (remove_shm) {
200*08b48e0bSAndroid Build Coastguard Worker
201*08b48e0bSAndroid Build Coastguard Worker if (shm.map) afl_shm_deinit(&shm);
202*08b48e0bSAndroid Build Coastguard Worker if (fsrv->use_shmem_fuzz) deinit_shmem(fsrv, shm_fuzz);
203*08b48e0bSAndroid Build Coastguard Worker
204*08b48e0bSAndroid Build Coastguard Worker }
205*08b48e0bSAndroid Build Coastguard Worker
206*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_killall();
207*08b48e0bSAndroid Build Coastguard Worker if (remove_out_file) unlink(out_file);
208*08b48e0bSAndroid Build Coastguard Worker
209*08b48e0bSAndroid Build Coastguard Worker }
210*08b48e0bSAndroid Build Coastguard Worker
211*08b48e0bSAndroid Build Coastguard Worker /* Read initial file. */
212*08b48e0bSAndroid Build Coastguard Worker
read_initial_file(void)213*08b48e0bSAndroid Build Coastguard Worker static void read_initial_file(void) {
214*08b48e0bSAndroid Build Coastguard Worker
215*08b48e0bSAndroid Build Coastguard Worker struct stat st;
216*08b48e0bSAndroid Build Coastguard Worker s32 fd = open(in_file, O_RDONLY);
217*08b48e0bSAndroid Build Coastguard Worker
218*08b48e0bSAndroid Build Coastguard Worker if (fd < 0) { PFATAL("Unable to open '%s'", in_file); }
219*08b48e0bSAndroid Build Coastguard Worker
220*08b48e0bSAndroid Build Coastguard Worker if (fstat(fd, &st) || !st.st_size) { FATAL("Zero-sized input file."); }
221*08b48e0bSAndroid Build Coastguard Worker
222*08b48e0bSAndroid Build Coastguard Worker if (st.st_size >= TMIN_MAX_FILE) {
223*08b48e0bSAndroid Build Coastguard Worker
224*08b48e0bSAndroid Build Coastguard Worker FATAL("Input file is too large (%ld MB max)", TMIN_MAX_FILE / 1024 / 1024);
225*08b48e0bSAndroid Build Coastguard Worker
226*08b48e0bSAndroid Build Coastguard Worker }
227*08b48e0bSAndroid Build Coastguard Worker
228*08b48e0bSAndroid Build Coastguard Worker in_len = st.st_size;
229*08b48e0bSAndroid Build Coastguard Worker in_data = ck_alloc_nozero(in_len);
230*08b48e0bSAndroid Build Coastguard Worker
231*08b48e0bSAndroid Build Coastguard Worker ck_read(fd, in_data, in_len, in_file);
232*08b48e0bSAndroid Build Coastguard Worker
233*08b48e0bSAndroid Build Coastguard Worker close(fd);
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker OKF("Read %u byte%s from '%s'.", in_len, in_len == 1 ? "" : "s", in_file);
236*08b48e0bSAndroid Build Coastguard Worker
237*08b48e0bSAndroid Build Coastguard Worker }
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker /* Write output file. */
240*08b48e0bSAndroid Build Coastguard Worker
write_to_file(u8 * path,u8 * mem,u32 len)241*08b48e0bSAndroid Build Coastguard Worker static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
242*08b48e0bSAndroid Build Coastguard Worker
243*08b48e0bSAndroid Build Coastguard Worker s32 ret;
244*08b48e0bSAndroid Build Coastguard Worker
245*08b48e0bSAndroid Build Coastguard Worker unlink(path); /* Ignore errors */
246*08b48e0bSAndroid Build Coastguard Worker
247*08b48e0bSAndroid Build Coastguard Worker ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
248*08b48e0bSAndroid Build Coastguard Worker
249*08b48e0bSAndroid Build Coastguard Worker if (ret < 0) { PFATAL("Unable to create '%s'", path); }
250*08b48e0bSAndroid Build Coastguard Worker
251*08b48e0bSAndroid Build Coastguard Worker ck_write(ret, mem, len, path);
252*08b48e0bSAndroid Build Coastguard Worker
253*08b48e0bSAndroid Build Coastguard Worker lseek(ret, 0, SEEK_SET);
254*08b48e0bSAndroid Build Coastguard Worker
255*08b48e0bSAndroid Build Coastguard Worker return ret;
256*08b48e0bSAndroid Build Coastguard Worker
257*08b48e0bSAndroid Build Coastguard Worker }
258*08b48e0bSAndroid Build Coastguard Worker
259*08b48e0bSAndroid Build Coastguard Worker /* Execute target application. Returns 0 if the changes are a dud, or
260*08b48e0bSAndroid Build Coastguard Worker 1 if they should be kept. */
261*08b48e0bSAndroid Build Coastguard Worker
tmin_run_target(afl_forkserver_t * fsrv,u8 * mem,u32 len,u8 first_run)262*08b48e0bSAndroid Build Coastguard Worker static u8 tmin_run_target(afl_forkserver_t *fsrv, u8 *mem, u32 len,
263*08b48e0bSAndroid Build Coastguard Worker u8 first_run) {
264*08b48e0bSAndroid Build Coastguard Worker
265*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_write_to_testcase(fsrv, mem, len);
266*08b48e0bSAndroid Build Coastguard Worker
267*08b48e0bSAndroid Build Coastguard Worker fsrv_run_result_t ret =
268*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
269*08b48e0bSAndroid Build Coastguard Worker
270*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_ERROR) { FATAL("Couldn't run child"); }
271*08b48e0bSAndroid Build Coastguard Worker
272*08b48e0bSAndroid Build Coastguard Worker if (stop_soon) {
273*08b48e0bSAndroid Build Coastguard Worker
274*08b48e0bSAndroid Build Coastguard Worker SAYF(cRST cLRD "\n+++ Minimization aborted by user +++\n" cRST);
275*08b48e0bSAndroid Build Coastguard Worker close(write_to_file(output_file, in_data, in_len));
276*08b48e0bSAndroid Build Coastguard Worker exit(1);
277*08b48e0bSAndroid Build Coastguard Worker
278*08b48e0bSAndroid Build Coastguard Worker }
279*08b48e0bSAndroid Build Coastguard Worker
280*08b48e0bSAndroid Build Coastguard Worker /* Always discard inputs that time out, unless we are in hang mode */
281*08b48e0bSAndroid Build Coastguard Worker
282*08b48e0bSAndroid Build Coastguard Worker if (hang_mode) {
283*08b48e0bSAndroid Build Coastguard Worker
284*08b48e0bSAndroid Build Coastguard Worker switch (ret) {
285*08b48e0bSAndroid Build Coastguard Worker
286*08b48e0bSAndroid Build Coastguard Worker case FSRV_RUN_TMOUT:
287*08b48e0bSAndroid Build Coastguard Worker return 1;
288*08b48e0bSAndroid Build Coastguard Worker case FSRV_RUN_CRASH:
289*08b48e0bSAndroid Build Coastguard Worker missed_crashes++;
290*08b48e0bSAndroid Build Coastguard Worker return 0;
291*08b48e0bSAndroid Build Coastguard Worker default:
292*08b48e0bSAndroid Build Coastguard Worker missed_hangs++;
293*08b48e0bSAndroid Build Coastguard Worker return 0;
294*08b48e0bSAndroid Build Coastguard Worker
295*08b48e0bSAndroid Build Coastguard Worker }
296*08b48e0bSAndroid Build Coastguard Worker
297*08b48e0bSAndroid Build Coastguard Worker }
298*08b48e0bSAndroid Build Coastguard Worker
299*08b48e0bSAndroid Build Coastguard Worker classify_counts(fsrv);
300*08b48e0bSAndroid Build Coastguard Worker apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
301*08b48e0bSAndroid Build Coastguard Worker
302*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_TMOUT) {
303*08b48e0bSAndroid Build Coastguard Worker
304*08b48e0bSAndroid Build Coastguard Worker missed_hangs++;
305*08b48e0bSAndroid Build Coastguard Worker return 0;
306*08b48e0bSAndroid Build Coastguard Worker
307*08b48e0bSAndroid Build Coastguard Worker }
308*08b48e0bSAndroid Build Coastguard Worker
309*08b48e0bSAndroid Build Coastguard Worker /* Handle crashing inputs depending on current mode. */
310*08b48e0bSAndroid Build Coastguard Worker
311*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_CRASH) {
312*08b48e0bSAndroid Build Coastguard Worker
313*08b48e0bSAndroid Build Coastguard Worker if (first_run) { crash_mode = 1; }
314*08b48e0bSAndroid Build Coastguard Worker
315*08b48e0bSAndroid Build Coastguard Worker if (crash_mode) {
316*08b48e0bSAndroid Build Coastguard Worker
317*08b48e0bSAndroid Build Coastguard Worker if (!exact_mode) { return 1; }
318*08b48e0bSAndroid Build Coastguard Worker
319*08b48e0bSAndroid Build Coastguard Worker } else {
320*08b48e0bSAndroid Build Coastguard Worker
321*08b48e0bSAndroid Build Coastguard Worker missed_crashes++;
322*08b48e0bSAndroid Build Coastguard Worker return 0;
323*08b48e0bSAndroid Build Coastguard Worker
324*08b48e0bSAndroid Build Coastguard Worker }
325*08b48e0bSAndroid Build Coastguard Worker
326*08b48e0bSAndroid Build Coastguard Worker } else {
327*08b48e0bSAndroid Build Coastguard Worker
328*08b48e0bSAndroid Build Coastguard Worker /* Handle non-crashing inputs appropriately. */
329*08b48e0bSAndroid Build Coastguard Worker
330*08b48e0bSAndroid Build Coastguard Worker if (crash_mode) {
331*08b48e0bSAndroid Build Coastguard Worker
332*08b48e0bSAndroid Build Coastguard Worker missed_paths++;
333*08b48e0bSAndroid Build Coastguard Worker return 0;
334*08b48e0bSAndroid Build Coastguard Worker
335*08b48e0bSAndroid Build Coastguard Worker }
336*08b48e0bSAndroid Build Coastguard Worker
337*08b48e0bSAndroid Build Coastguard Worker }
338*08b48e0bSAndroid Build Coastguard Worker
339*08b48e0bSAndroid Build Coastguard Worker if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
340*08b48e0bSAndroid Build Coastguard Worker
341*08b48e0bSAndroid Build Coastguard Worker u64 cksum = hash64(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
342*08b48e0bSAndroid Build Coastguard Worker
343*08b48e0bSAndroid Build Coastguard Worker if (first_run) { orig_cksum = cksum; }
344*08b48e0bSAndroid Build Coastguard Worker
345*08b48e0bSAndroid Build Coastguard Worker if (orig_cksum == cksum) { return 1; }
346*08b48e0bSAndroid Build Coastguard Worker
347*08b48e0bSAndroid Build Coastguard Worker missed_paths++;
348*08b48e0bSAndroid Build Coastguard Worker return 0;
349*08b48e0bSAndroid Build Coastguard Worker
350*08b48e0bSAndroid Build Coastguard Worker }
351*08b48e0bSAndroid Build Coastguard Worker
352*08b48e0bSAndroid Build Coastguard Worker /* Actually minimize! */
353*08b48e0bSAndroid Build Coastguard Worker
minimize(afl_forkserver_t * fsrv)354*08b48e0bSAndroid Build Coastguard Worker static void minimize(afl_forkserver_t *fsrv) {
355*08b48e0bSAndroid Build Coastguard Worker
356*08b48e0bSAndroid Build Coastguard Worker static u32 alpha_map[256];
357*08b48e0bSAndroid Build Coastguard Worker
358*08b48e0bSAndroid Build Coastguard Worker u8 *tmp_buf = ck_alloc_nozero(in_len);
359*08b48e0bSAndroid Build Coastguard Worker u32 orig_len = in_len, stage_o_len;
360*08b48e0bSAndroid Build Coastguard Worker
361*08b48e0bSAndroid Build Coastguard Worker u32 del_len, set_len, del_pos, set_pos, i, alpha_size, cur_pass = 0;
362*08b48e0bSAndroid Build Coastguard Worker u32 syms_removed, alpha_del0 = 0, alpha_del1, alpha_del2, alpha_d_total = 0;
363*08b48e0bSAndroid Build Coastguard Worker u8 changed_any, prev_del;
364*08b48e0bSAndroid Build Coastguard Worker
365*08b48e0bSAndroid Build Coastguard Worker /***********************
366*08b48e0bSAndroid Build Coastguard Worker * BLOCK NORMALIZATION *
367*08b48e0bSAndroid Build Coastguard Worker ***********************/
368*08b48e0bSAndroid Build Coastguard Worker
369*08b48e0bSAndroid Build Coastguard Worker set_len = next_pow2(in_len / TMIN_SET_STEPS);
370*08b48e0bSAndroid Build Coastguard Worker set_pos = 0;
371*08b48e0bSAndroid Build Coastguard Worker
372*08b48e0bSAndroid Build Coastguard Worker if (set_len < TMIN_SET_MIN_SIZE) { set_len = TMIN_SET_MIN_SIZE; }
373*08b48e0bSAndroid Build Coastguard Worker
374*08b48e0bSAndroid Build Coastguard Worker ACTF(cBRI "Stage #0: " cRST "One-time block normalization...");
375*08b48e0bSAndroid Build Coastguard Worker
376*08b48e0bSAndroid Build Coastguard Worker while (set_pos < in_len) {
377*08b48e0bSAndroid Build Coastguard Worker
378*08b48e0bSAndroid Build Coastguard Worker u32 use_len = MIN(set_len, in_len - set_pos);
379*08b48e0bSAndroid Build Coastguard Worker
380*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < use_len; i++) {
381*08b48e0bSAndroid Build Coastguard Worker
382*08b48e0bSAndroid Build Coastguard Worker if (in_data[set_pos + i] != '0') { break; }
383*08b48e0bSAndroid Build Coastguard Worker
384*08b48e0bSAndroid Build Coastguard Worker }
385*08b48e0bSAndroid Build Coastguard Worker
386*08b48e0bSAndroid Build Coastguard Worker if (i != use_len) {
387*08b48e0bSAndroid Build Coastguard Worker
388*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp_buf, in_data, in_len);
389*08b48e0bSAndroid Build Coastguard Worker memset(tmp_buf + set_pos, '0', use_len);
390*08b48e0bSAndroid Build Coastguard Worker
391*08b48e0bSAndroid Build Coastguard Worker u8 res;
392*08b48e0bSAndroid Build Coastguard Worker res = tmin_run_target(fsrv, tmp_buf, in_len, 0);
393*08b48e0bSAndroid Build Coastguard Worker
394*08b48e0bSAndroid Build Coastguard Worker if (res) {
395*08b48e0bSAndroid Build Coastguard Worker
396*08b48e0bSAndroid Build Coastguard Worker memset(in_data + set_pos, '0', use_len);
397*08b48e0bSAndroid Build Coastguard Worker /* changed_any = 1; value is not used */
398*08b48e0bSAndroid Build Coastguard Worker alpha_del0 += use_len;
399*08b48e0bSAndroid Build Coastguard Worker
400*08b48e0bSAndroid Build Coastguard Worker }
401*08b48e0bSAndroid Build Coastguard Worker
402*08b48e0bSAndroid Build Coastguard Worker }
403*08b48e0bSAndroid Build Coastguard Worker
404*08b48e0bSAndroid Build Coastguard Worker set_pos += set_len;
405*08b48e0bSAndroid Build Coastguard Worker
406*08b48e0bSAndroid Build Coastguard Worker }
407*08b48e0bSAndroid Build Coastguard Worker
408*08b48e0bSAndroid Build Coastguard Worker alpha_d_total += alpha_del0;
409*08b48e0bSAndroid Build Coastguard Worker
410*08b48e0bSAndroid Build Coastguard Worker OKF("Block normalization complete, %u byte%s replaced.", alpha_del0,
411*08b48e0bSAndroid Build Coastguard Worker alpha_del0 == 1 ? "" : "s");
412*08b48e0bSAndroid Build Coastguard Worker
413*08b48e0bSAndroid Build Coastguard Worker next_pass:
414*08b48e0bSAndroid Build Coastguard Worker
415*08b48e0bSAndroid Build Coastguard Worker ACTF(cYEL "--- " cBRI "Pass #%u " cYEL "---", ++cur_pass);
416*08b48e0bSAndroid Build Coastguard Worker changed_any = 0;
417*08b48e0bSAndroid Build Coastguard Worker
418*08b48e0bSAndroid Build Coastguard Worker /******************
419*08b48e0bSAndroid Build Coastguard Worker * BLOCK DELETION *
420*08b48e0bSAndroid Build Coastguard Worker ******************/
421*08b48e0bSAndroid Build Coastguard Worker
422*08b48e0bSAndroid Build Coastguard Worker del_len = next_pow2(in_len / TRIM_START_STEPS);
423*08b48e0bSAndroid Build Coastguard Worker stage_o_len = in_len;
424*08b48e0bSAndroid Build Coastguard Worker
425*08b48e0bSAndroid Build Coastguard Worker ACTF(cBRI "Stage #1: " cRST "Removing blocks of data...");
426*08b48e0bSAndroid Build Coastguard Worker
427*08b48e0bSAndroid Build Coastguard Worker next_del_blksize:
428*08b48e0bSAndroid Build Coastguard Worker
429*08b48e0bSAndroid Build Coastguard Worker if (!del_len) { del_len = 1; }
430*08b48e0bSAndroid Build Coastguard Worker del_pos = 0;
431*08b48e0bSAndroid Build Coastguard Worker prev_del = 1;
432*08b48e0bSAndroid Build Coastguard Worker
433*08b48e0bSAndroid Build Coastguard Worker SAYF(cGRA " Block length = %u, remaining size = %u\n" cRST, del_len,
434*08b48e0bSAndroid Build Coastguard Worker in_len);
435*08b48e0bSAndroid Build Coastguard Worker
436*08b48e0bSAndroid Build Coastguard Worker while (del_pos < in_len) {
437*08b48e0bSAndroid Build Coastguard Worker
438*08b48e0bSAndroid Build Coastguard Worker u8 res;
439*08b48e0bSAndroid Build Coastguard Worker s32 tail_len;
440*08b48e0bSAndroid Build Coastguard Worker
441*08b48e0bSAndroid Build Coastguard Worker tail_len = in_len - del_pos - del_len;
442*08b48e0bSAndroid Build Coastguard Worker if (tail_len < 0) { tail_len = 0; }
443*08b48e0bSAndroid Build Coastguard Worker
444*08b48e0bSAndroid Build Coastguard Worker /* If we have processed at least one full block (initially, prev_del == 1),
445*08b48e0bSAndroid Build Coastguard Worker and we did so without deleting the previous one, and we aren't at the
446*08b48e0bSAndroid Build Coastguard Worker very end of the buffer (tail_len > 0), and the current block is the same
447*08b48e0bSAndroid Build Coastguard Worker as the previous one... skip this step as a no-op. */
448*08b48e0bSAndroid Build Coastguard Worker
449*08b48e0bSAndroid Build Coastguard Worker if (!prev_del && tail_len &&
450*08b48e0bSAndroid Build Coastguard Worker !memcmp(in_data + del_pos - del_len, in_data + del_pos, del_len)) {
451*08b48e0bSAndroid Build Coastguard Worker
452*08b48e0bSAndroid Build Coastguard Worker del_pos += del_len;
453*08b48e0bSAndroid Build Coastguard Worker continue;
454*08b48e0bSAndroid Build Coastguard Worker
455*08b48e0bSAndroid Build Coastguard Worker }
456*08b48e0bSAndroid Build Coastguard Worker
457*08b48e0bSAndroid Build Coastguard Worker prev_del = 0;
458*08b48e0bSAndroid Build Coastguard Worker
459*08b48e0bSAndroid Build Coastguard Worker /* Head */
460*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp_buf, in_data, del_pos);
461*08b48e0bSAndroid Build Coastguard Worker
462*08b48e0bSAndroid Build Coastguard Worker /* Tail */
463*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);
464*08b48e0bSAndroid Build Coastguard Worker
465*08b48e0bSAndroid Build Coastguard Worker res = tmin_run_target(fsrv, tmp_buf, del_pos + tail_len, 0);
466*08b48e0bSAndroid Build Coastguard Worker
467*08b48e0bSAndroid Build Coastguard Worker if (res) {
468*08b48e0bSAndroid Build Coastguard Worker
469*08b48e0bSAndroid Build Coastguard Worker memcpy(in_data, tmp_buf, del_pos + tail_len);
470*08b48e0bSAndroid Build Coastguard Worker prev_del = 1;
471*08b48e0bSAndroid Build Coastguard Worker in_len = del_pos + tail_len;
472*08b48e0bSAndroid Build Coastguard Worker
473*08b48e0bSAndroid Build Coastguard Worker changed_any = 1;
474*08b48e0bSAndroid Build Coastguard Worker
475*08b48e0bSAndroid Build Coastguard Worker } else {
476*08b48e0bSAndroid Build Coastguard Worker
477*08b48e0bSAndroid Build Coastguard Worker del_pos += del_len;
478*08b48e0bSAndroid Build Coastguard Worker
479*08b48e0bSAndroid Build Coastguard Worker }
480*08b48e0bSAndroid Build Coastguard Worker
481*08b48e0bSAndroid Build Coastguard Worker }
482*08b48e0bSAndroid Build Coastguard Worker
483*08b48e0bSAndroid Build Coastguard Worker if (del_len > 1 && in_len >= 1) {
484*08b48e0bSAndroid Build Coastguard Worker
485*08b48e0bSAndroid Build Coastguard Worker del_len /= 2;
486*08b48e0bSAndroid Build Coastguard Worker goto next_del_blksize;
487*08b48e0bSAndroid Build Coastguard Worker
488*08b48e0bSAndroid Build Coastguard Worker }
489*08b48e0bSAndroid Build Coastguard Worker
490*08b48e0bSAndroid Build Coastguard Worker OKF("Block removal complete, %u bytes deleted.", stage_o_len - in_len);
491*08b48e0bSAndroid Build Coastguard Worker
492*08b48e0bSAndroid Build Coastguard Worker if (!in_len && changed_any) {
493*08b48e0bSAndroid Build Coastguard Worker
494*08b48e0bSAndroid Build Coastguard Worker WARNF(cLRD
495*08b48e0bSAndroid Build Coastguard Worker "Down to zero bytes - check the command line and mem limit!" cRST);
496*08b48e0bSAndroid Build Coastguard Worker
497*08b48e0bSAndroid Build Coastguard Worker }
498*08b48e0bSAndroid Build Coastguard Worker
499*08b48e0bSAndroid Build Coastguard Worker if (cur_pass > 1 && !changed_any) { goto finalize_all; }
500*08b48e0bSAndroid Build Coastguard Worker
501*08b48e0bSAndroid Build Coastguard Worker /*************************
502*08b48e0bSAndroid Build Coastguard Worker * ALPHABET MINIMIZATION *
503*08b48e0bSAndroid Build Coastguard Worker *************************/
504*08b48e0bSAndroid Build Coastguard Worker
505*08b48e0bSAndroid Build Coastguard Worker alpha_size = 0;
506*08b48e0bSAndroid Build Coastguard Worker alpha_del1 = 0;
507*08b48e0bSAndroid Build Coastguard Worker syms_removed = 0;
508*08b48e0bSAndroid Build Coastguard Worker
509*08b48e0bSAndroid Build Coastguard Worker memset(alpha_map, 0, sizeof(alpha_map));
510*08b48e0bSAndroid Build Coastguard Worker
511*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < in_len; i++) {
512*08b48e0bSAndroid Build Coastguard Worker
513*08b48e0bSAndroid Build Coastguard Worker if (!alpha_map[in_data[i]]) { alpha_size++; }
514*08b48e0bSAndroid Build Coastguard Worker alpha_map[in_data[i]]++;
515*08b48e0bSAndroid Build Coastguard Worker
516*08b48e0bSAndroid Build Coastguard Worker }
517*08b48e0bSAndroid Build Coastguard Worker
518*08b48e0bSAndroid Build Coastguard Worker ACTF(cBRI "Stage #2: " cRST "Minimizing symbols (%u code point%s)...",
519*08b48e0bSAndroid Build Coastguard Worker alpha_size, alpha_size == 1 ? "" : "s");
520*08b48e0bSAndroid Build Coastguard Worker
521*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < 256; i++) {
522*08b48e0bSAndroid Build Coastguard Worker
523*08b48e0bSAndroid Build Coastguard Worker u32 r;
524*08b48e0bSAndroid Build Coastguard Worker u8 res;
525*08b48e0bSAndroid Build Coastguard Worker
526*08b48e0bSAndroid Build Coastguard Worker if (i == '0' || !alpha_map[i]) { continue; }
527*08b48e0bSAndroid Build Coastguard Worker
528*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp_buf, in_data, in_len);
529*08b48e0bSAndroid Build Coastguard Worker
530*08b48e0bSAndroid Build Coastguard Worker for (r = 0; r < in_len; r++) {
531*08b48e0bSAndroid Build Coastguard Worker
532*08b48e0bSAndroid Build Coastguard Worker if (tmp_buf[r] == i) { tmp_buf[r] = '0'; }
533*08b48e0bSAndroid Build Coastguard Worker
534*08b48e0bSAndroid Build Coastguard Worker }
535*08b48e0bSAndroid Build Coastguard Worker
536*08b48e0bSAndroid Build Coastguard Worker res = tmin_run_target(fsrv, tmp_buf, in_len, 0);
537*08b48e0bSAndroid Build Coastguard Worker
538*08b48e0bSAndroid Build Coastguard Worker if (res) {
539*08b48e0bSAndroid Build Coastguard Worker
540*08b48e0bSAndroid Build Coastguard Worker memcpy(in_data, tmp_buf, in_len);
541*08b48e0bSAndroid Build Coastguard Worker syms_removed++;
542*08b48e0bSAndroid Build Coastguard Worker alpha_del1 += alpha_map[i];
543*08b48e0bSAndroid Build Coastguard Worker changed_any = 1;
544*08b48e0bSAndroid Build Coastguard Worker
545*08b48e0bSAndroid Build Coastguard Worker }
546*08b48e0bSAndroid Build Coastguard Worker
547*08b48e0bSAndroid Build Coastguard Worker }
548*08b48e0bSAndroid Build Coastguard Worker
549*08b48e0bSAndroid Build Coastguard Worker alpha_d_total += alpha_del1;
550*08b48e0bSAndroid Build Coastguard Worker
551*08b48e0bSAndroid Build Coastguard Worker OKF("Symbol minimization finished, %u symbol%s (%u byte%s) replaced.",
552*08b48e0bSAndroid Build Coastguard Worker syms_removed, syms_removed == 1 ? "" : "s", alpha_del1,
553*08b48e0bSAndroid Build Coastguard Worker alpha_del1 == 1 ? "" : "s");
554*08b48e0bSAndroid Build Coastguard Worker
555*08b48e0bSAndroid Build Coastguard Worker /**************************
556*08b48e0bSAndroid Build Coastguard Worker * CHARACTER MINIMIZATION *
557*08b48e0bSAndroid Build Coastguard Worker **************************/
558*08b48e0bSAndroid Build Coastguard Worker
559*08b48e0bSAndroid Build Coastguard Worker alpha_del2 = 0;
560*08b48e0bSAndroid Build Coastguard Worker
561*08b48e0bSAndroid Build Coastguard Worker ACTF(cBRI "Stage #3: " cRST "Character minimization...");
562*08b48e0bSAndroid Build Coastguard Worker
563*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp_buf, in_data, in_len);
564*08b48e0bSAndroid Build Coastguard Worker
565*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < in_len; i++) {
566*08b48e0bSAndroid Build Coastguard Worker
567*08b48e0bSAndroid Build Coastguard Worker u8 res, orig = tmp_buf[i];
568*08b48e0bSAndroid Build Coastguard Worker
569*08b48e0bSAndroid Build Coastguard Worker if (orig == '0') { continue; }
570*08b48e0bSAndroid Build Coastguard Worker tmp_buf[i] = '0';
571*08b48e0bSAndroid Build Coastguard Worker
572*08b48e0bSAndroid Build Coastguard Worker res = tmin_run_target(fsrv, tmp_buf, in_len, 0);
573*08b48e0bSAndroid Build Coastguard Worker
574*08b48e0bSAndroid Build Coastguard Worker if (res) {
575*08b48e0bSAndroid Build Coastguard Worker
576*08b48e0bSAndroid Build Coastguard Worker in_data[i] = '0';
577*08b48e0bSAndroid Build Coastguard Worker alpha_del2++;
578*08b48e0bSAndroid Build Coastguard Worker changed_any = 1;
579*08b48e0bSAndroid Build Coastguard Worker
580*08b48e0bSAndroid Build Coastguard Worker } else {
581*08b48e0bSAndroid Build Coastguard Worker
582*08b48e0bSAndroid Build Coastguard Worker tmp_buf[i] = orig;
583*08b48e0bSAndroid Build Coastguard Worker
584*08b48e0bSAndroid Build Coastguard Worker }
585*08b48e0bSAndroid Build Coastguard Worker
586*08b48e0bSAndroid Build Coastguard Worker }
587*08b48e0bSAndroid Build Coastguard Worker
588*08b48e0bSAndroid Build Coastguard Worker alpha_d_total += alpha_del2;
589*08b48e0bSAndroid Build Coastguard Worker
590*08b48e0bSAndroid Build Coastguard Worker OKF("Character minimization done, %u byte%s replaced.", alpha_del2,
591*08b48e0bSAndroid Build Coastguard Worker alpha_del2 == 1 ? "" : "s");
592*08b48e0bSAndroid Build Coastguard Worker
593*08b48e0bSAndroid Build Coastguard Worker if (changed_any) { goto next_pass; }
594*08b48e0bSAndroid Build Coastguard Worker
595*08b48e0bSAndroid Build Coastguard Worker finalize_all:
596*08b48e0bSAndroid Build Coastguard Worker
597*08b48e0bSAndroid Build Coastguard Worker if (tmp_buf) { ck_free(tmp_buf); }
598*08b48e0bSAndroid Build Coastguard Worker
599*08b48e0bSAndroid Build Coastguard Worker if (hang_mode) {
600*08b48e0bSAndroid Build Coastguard Worker
601*08b48e0bSAndroid Build Coastguard Worker SAYF("\n" cGRA " File size reduced by : " cRST
602*08b48e0bSAndroid Build Coastguard Worker "%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST
603*08b48e0bSAndroid Build Coastguard Worker "%0.02f%%\n" cGRA " Number of execs done : " cRST "%llu\n" cGRA
604*08b48e0bSAndroid Build Coastguard Worker " Fruitless execs : " cRST "termination=%u crash=%u\n\n",
605*08b48e0bSAndroid Build Coastguard Worker 100 - ((double)in_len) * 100 / orig_len, in_len,
606*08b48e0bSAndroid Build Coastguard Worker in_len == 1 ? "" : "s",
607*08b48e0bSAndroid Build Coastguard Worker ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1),
608*08b48e0bSAndroid Build Coastguard Worker fsrv->total_execs, missed_paths, missed_crashes);
609*08b48e0bSAndroid Build Coastguard Worker return;
610*08b48e0bSAndroid Build Coastguard Worker
611*08b48e0bSAndroid Build Coastguard Worker }
612*08b48e0bSAndroid Build Coastguard Worker
613*08b48e0bSAndroid Build Coastguard Worker SAYF("\n" cGRA " File size reduced by : " cRST
614*08b48e0bSAndroid Build Coastguard Worker "%0.02f%% (to %u byte%s)\n" cGRA " Characters simplified : " cRST
615*08b48e0bSAndroid Build Coastguard Worker "%0.02f%%\n" cGRA " Number of execs done : " cRST "%llu\n" cGRA
616*08b48e0bSAndroid Build Coastguard Worker " Fruitless execs : " cRST "path=%u crash=%u hang=%s%u\n\n",
617*08b48e0bSAndroid Build Coastguard Worker 100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? "" : "s",
618*08b48e0bSAndroid Build Coastguard Worker ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1),
619*08b48e0bSAndroid Build Coastguard Worker fsrv->total_execs, missed_paths, missed_crashes,
620*08b48e0bSAndroid Build Coastguard Worker missed_hangs ? cLRD : "", missed_hangs);
621*08b48e0bSAndroid Build Coastguard Worker
622*08b48e0bSAndroid Build Coastguard Worker if (fsrv->total_execs > 50 && missed_hangs * 10 > fsrv->total_execs &&
623*08b48e0bSAndroid Build Coastguard Worker !hang_mode) {
624*08b48e0bSAndroid Build Coastguard Worker
625*08b48e0bSAndroid Build Coastguard Worker WARNF(cLRD "Frequent timeouts - results may be skewed." cRST);
626*08b48e0bSAndroid Build Coastguard Worker
627*08b48e0bSAndroid Build Coastguard Worker }
628*08b48e0bSAndroid Build Coastguard Worker
629*08b48e0bSAndroid Build Coastguard Worker }
630*08b48e0bSAndroid Build Coastguard Worker
631*08b48e0bSAndroid Build Coastguard Worker /* Handle Ctrl-C and the like. */
632*08b48e0bSAndroid Build Coastguard Worker
handle_stop_sig(int sig)633*08b48e0bSAndroid Build Coastguard Worker static void handle_stop_sig(int sig) {
634*08b48e0bSAndroid Build Coastguard Worker
635*08b48e0bSAndroid Build Coastguard Worker (void)sig;
636*08b48e0bSAndroid Build Coastguard Worker stop_soon = 1;
637*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_killall();
638*08b48e0bSAndroid Build Coastguard Worker
639*08b48e0bSAndroid Build Coastguard Worker }
640*08b48e0bSAndroid Build Coastguard Worker
641*08b48e0bSAndroid Build Coastguard Worker /* Do basic preparations - persistent fds, filenames, etc. */
642*08b48e0bSAndroid Build Coastguard Worker
set_up_environment(afl_forkserver_t * fsrv,char ** argv)643*08b48e0bSAndroid Build Coastguard Worker static void set_up_environment(afl_forkserver_t *fsrv, char **argv) {
644*08b48e0bSAndroid Build Coastguard Worker
645*08b48e0bSAndroid Build Coastguard Worker u8 *x;
646*08b48e0bSAndroid Build Coastguard Worker char *afl_preload;
647*08b48e0bSAndroid Build Coastguard Worker char *frida_afl_preload = NULL;
648*08b48e0bSAndroid Build Coastguard Worker
649*08b48e0bSAndroid Build Coastguard Worker fsrv->dev_null_fd = open("/dev/null", O_RDWR);
650*08b48e0bSAndroid Build Coastguard Worker if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
651*08b48e0bSAndroid Build Coastguard Worker
652*08b48e0bSAndroid Build Coastguard Worker if (!out_file) {
653*08b48e0bSAndroid Build Coastguard Worker
654*08b48e0bSAndroid Build Coastguard Worker u8 *use_dir = ".";
655*08b48e0bSAndroid Build Coastguard Worker
656*08b48e0bSAndroid Build Coastguard Worker if (access(use_dir, R_OK | W_OK | X_OK)) {
657*08b48e0bSAndroid Build Coastguard Worker
658*08b48e0bSAndroid Build Coastguard Worker use_dir = get_afl_env("TMPDIR");
659*08b48e0bSAndroid Build Coastguard Worker if (!use_dir) { use_dir = "/tmp"; }
660*08b48e0bSAndroid Build Coastguard Worker
661*08b48e0bSAndroid Build Coastguard Worker }
662*08b48e0bSAndroid Build Coastguard Worker
663*08b48e0bSAndroid Build Coastguard Worker out_file = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, (u32)getpid());
664*08b48e0bSAndroid Build Coastguard Worker remove_out_file = 1;
665*08b48e0bSAndroid Build Coastguard Worker
666*08b48e0bSAndroid Build Coastguard Worker }
667*08b48e0bSAndroid Build Coastguard Worker
668*08b48e0bSAndroid Build Coastguard Worker unlink(out_file);
669*08b48e0bSAndroid Build Coastguard Worker
670*08b48e0bSAndroid Build Coastguard Worker fsrv->out_file = out_file;
671*08b48e0bSAndroid Build Coastguard Worker fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
672*08b48e0bSAndroid Build Coastguard Worker
673*08b48e0bSAndroid Build Coastguard Worker if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
674*08b48e0bSAndroid Build Coastguard Worker
675*08b48e0bSAndroid Build Coastguard Worker /* Set sane defaults... */
676*08b48e0bSAndroid Build Coastguard Worker
677*08b48e0bSAndroid Build Coastguard Worker x = get_afl_env("MSAN_OPTIONS");
678*08b48e0bSAndroid Build Coastguard Worker
679*08b48e0bSAndroid Build Coastguard Worker if (x) {
680*08b48e0bSAndroid Build Coastguard Worker
681*08b48e0bSAndroid Build Coastguard Worker if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) {
682*08b48e0bSAndroid Build Coastguard Worker
683*08b48e0bSAndroid Build Coastguard Worker FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
684*08b48e0bSAndroid Build Coastguard Worker MSAN_ERROR) " - please fix!");
685*08b48e0bSAndroid Build Coastguard Worker
686*08b48e0bSAndroid Build Coastguard Worker }
687*08b48e0bSAndroid Build Coastguard Worker
688*08b48e0bSAndroid Build Coastguard Worker }
689*08b48e0bSAndroid Build Coastguard Worker
690*08b48e0bSAndroid Build Coastguard Worker set_sanitizer_defaults();
691*08b48e0bSAndroid Build Coastguard Worker
692*08b48e0bSAndroid Build Coastguard Worker if (get_afl_env("AFL_PRELOAD")) {
693*08b48e0bSAndroid Build Coastguard Worker
694*08b48e0bSAndroid Build Coastguard Worker if (fsrv->qemu_mode) {
695*08b48e0bSAndroid Build Coastguard Worker
696*08b48e0bSAndroid Build Coastguard Worker /* afl-qemu-trace takes care of converting AFL_PRELOAD. */
697*08b48e0bSAndroid Build Coastguard Worker
698*08b48e0bSAndroid Build Coastguard Worker } else if (fsrv->frida_mode) {
699*08b48e0bSAndroid Build Coastguard Worker
700*08b48e0bSAndroid Build Coastguard Worker afl_preload = getenv("AFL_PRELOAD");
701*08b48e0bSAndroid Build Coastguard Worker u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
702*08b48e0bSAndroid Build Coastguard Worker if (afl_preload) {
703*08b48e0bSAndroid Build Coastguard Worker
704*08b48e0bSAndroid Build Coastguard Worker frida_afl_preload = alloc_printf("%s:%s", afl_preload, frida_binary);
705*08b48e0bSAndroid Build Coastguard Worker
706*08b48e0bSAndroid Build Coastguard Worker } else {
707*08b48e0bSAndroid Build Coastguard Worker
708*08b48e0bSAndroid Build Coastguard Worker frida_afl_preload = alloc_printf("%s", frida_binary);
709*08b48e0bSAndroid Build Coastguard Worker
710*08b48e0bSAndroid Build Coastguard Worker }
711*08b48e0bSAndroid Build Coastguard Worker
712*08b48e0bSAndroid Build Coastguard Worker ck_free(frida_binary);
713*08b48e0bSAndroid Build Coastguard Worker
714*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", frida_afl_preload, 1);
715*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", frida_afl_preload, 1);
716*08b48e0bSAndroid Build Coastguard Worker
717*08b48e0bSAndroid Build Coastguard Worker } else {
718*08b48e0bSAndroid Build Coastguard Worker
719*08b48e0bSAndroid Build Coastguard Worker /* CoreSight mode uses the default behavior. */
720*08b48e0bSAndroid Build Coastguard Worker
721*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
722*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
723*08b48e0bSAndroid Build Coastguard Worker
724*08b48e0bSAndroid Build Coastguard Worker }
725*08b48e0bSAndroid Build Coastguard Worker
726*08b48e0bSAndroid Build Coastguard Worker } else if (fsrv->frida_mode) {
727*08b48e0bSAndroid Build Coastguard Worker
728*08b48e0bSAndroid Build Coastguard Worker u8 *frida_binary = find_afl_binary(argv[0], "afl-frida-trace.so");
729*08b48e0bSAndroid Build Coastguard Worker setenv("LD_PRELOAD", frida_binary, 1);
730*08b48e0bSAndroid Build Coastguard Worker setenv("DYLD_INSERT_LIBRARIES", frida_binary, 1);
731*08b48e0bSAndroid Build Coastguard Worker ck_free(frida_binary);
732*08b48e0bSAndroid Build Coastguard Worker
733*08b48e0bSAndroid Build Coastguard Worker }
734*08b48e0bSAndroid Build Coastguard Worker
735*08b48e0bSAndroid Build Coastguard Worker if (frida_afl_preload) { ck_free(frida_afl_preload); }
736*08b48e0bSAndroid Build Coastguard Worker
737*08b48e0bSAndroid Build Coastguard Worker }
738*08b48e0bSAndroid Build Coastguard Worker
739*08b48e0bSAndroid Build Coastguard Worker /* Setup signal handlers, duh. */
740*08b48e0bSAndroid Build Coastguard Worker
setup_signal_handlers(void)741*08b48e0bSAndroid Build Coastguard Worker static void setup_signal_handlers(void) {
742*08b48e0bSAndroid Build Coastguard Worker
743*08b48e0bSAndroid Build Coastguard Worker struct sigaction sa;
744*08b48e0bSAndroid Build Coastguard Worker
745*08b48e0bSAndroid Build Coastguard Worker sa.sa_handler = NULL;
746*08b48e0bSAndroid Build Coastguard Worker #ifdef SA_RESTART
747*08b48e0bSAndroid Build Coastguard Worker sa.sa_flags = SA_RESTART;
748*08b48e0bSAndroid Build Coastguard Worker #else
749*08b48e0bSAndroid Build Coastguard Worker sa.sa_flags = 0;
750*08b48e0bSAndroid Build Coastguard Worker #endif
751*08b48e0bSAndroid Build Coastguard Worker sa.sa_sigaction = NULL;
752*08b48e0bSAndroid Build Coastguard Worker
753*08b48e0bSAndroid Build Coastguard Worker sigemptyset(&sa.sa_mask);
754*08b48e0bSAndroid Build Coastguard Worker
755*08b48e0bSAndroid Build Coastguard Worker /* Various ways of saying "stop". */
756*08b48e0bSAndroid Build Coastguard Worker
757*08b48e0bSAndroid Build Coastguard Worker sa.sa_handler = handle_stop_sig;
758*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGHUP, &sa, NULL);
759*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGINT, &sa, NULL);
760*08b48e0bSAndroid Build Coastguard Worker sigaction(SIGTERM, &sa, NULL);
761*08b48e0bSAndroid Build Coastguard Worker
762*08b48e0bSAndroid Build Coastguard Worker }
763*08b48e0bSAndroid Build Coastguard Worker
764*08b48e0bSAndroid Build Coastguard Worker /* Display usage hints. */
765*08b48e0bSAndroid Build Coastguard Worker
usage(u8 * argv0)766*08b48e0bSAndroid Build Coastguard Worker static void usage(u8 *argv0) {
767*08b48e0bSAndroid Build Coastguard Worker
768*08b48e0bSAndroid Build Coastguard Worker SAYF(
769*08b48e0bSAndroid Build Coastguard Worker "\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
770*08b48e0bSAndroid Build Coastguard Worker
771*08b48e0bSAndroid Build Coastguard Worker "Required parameters:\n"
772*08b48e0bSAndroid Build Coastguard Worker
773*08b48e0bSAndroid Build Coastguard Worker " -i file - input test case to be shrunk by the tool\n"
774*08b48e0bSAndroid Build Coastguard Worker " -o file - final output location for the minimized data\n\n"
775*08b48e0bSAndroid Build Coastguard Worker
776*08b48e0bSAndroid Build Coastguard Worker "Execution control settings:\n"
777*08b48e0bSAndroid Build Coastguard Worker
778*08b48e0bSAndroid Build Coastguard Worker " -f file - input file read by the tested program (stdin)\n"
779*08b48e0bSAndroid Build Coastguard Worker " -t msec - timeout for each run (%u ms)\n"
780*08b48e0bSAndroid Build Coastguard Worker " -m megs - memory limit for child process (%u MB)\n"
781*08b48e0bSAndroid Build Coastguard Worker #if defined(__linux__) && defined(__aarch64__)
782*08b48e0bSAndroid Build Coastguard Worker " -A - use binary-only instrumentation (ARM CoreSight mode)\n"
783*08b48e0bSAndroid Build Coastguard Worker #endif
784*08b48e0bSAndroid Build Coastguard Worker " -O - use binary-only instrumentation (FRIDA mode)\n"
785*08b48e0bSAndroid Build Coastguard Worker #if defined(__linux__)
786*08b48e0bSAndroid Build Coastguard Worker " -Q - use binary-only instrumentation (QEMU mode)\n"
787*08b48e0bSAndroid Build Coastguard Worker " -U - use unicorn-based instrumentation (Unicorn mode)\n"
788*08b48e0bSAndroid Build Coastguard Worker " -W - use qemu-based instrumentation with Wine (Wine "
789*08b48e0bSAndroid Build Coastguard Worker "mode)\n"
790*08b48e0bSAndroid Build Coastguard Worker " (Not necessary, here for consistency with other afl-* "
791*08b48e0bSAndroid Build Coastguard Worker "tools)\n"
792*08b48e0bSAndroid Build Coastguard Worker " -X - use Nyx mode\n"
793*08b48e0bSAndroid Build Coastguard Worker #endif
794*08b48e0bSAndroid Build Coastguard Worker "\n"
795*08b48e0bSAndroid Build Coastguard Worker
796*08b48e0bSAndroid Build Coastguard Worker "Minimization settings:\n"
797*08b48e0bSAndroid Build Coastguard Worker
798*08b48e0bSAndroid Build Coastguard Worker " -e - solve for edge coverage only, ignore hit counts\n"
799*08b48e0bSAndroid Build Coastguard Worker " -x - treat non-zero exit codes as crashes\n\n"
800*08b48e0bSAndroid Build Coastguard Worker " -H - minimize a hang (hang mode)\n"
801*08b48e0bSAndroid Build Coastguard Worker
802*08b48e0bSAndroid Build Coastguard Worker "For additional tips, please consult %s/README.md.\n\n"
803*08b48e0bSAndroid Build Coastguard Worker
804*08b48e0bSAndroid Build Coastguard Worker "Environment variables used:\n"
805*08b48e0bSAndroid Build Coastguard Worker "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n"
806*08b48e0bSAndroid Build Coastguard Worker "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n"
807*08b48e0bSAndroid Build Coastguard Worker "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
808*08b48e0bSAndroid Build Coastguard Worker " (default: SIGKILL)\n"
809*08b48e0bSAndroid Build Coastguard Worker "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
810*08b48e0bSAndroid Build Coastguard Worker " (default: SIGTERM). If unset and AFL_KILL_SIGNAL is\n"
811*08b48e0bSAndroid Build Coastguard Worker " set, that value will be used.\n"
812*08b48e0bSAndroid Build Coastguard Worker "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
813*08b48e0bSAndroid Build Coastguard Worker " the target was compiled for\n"
814*08b48e0bSAndroid Build Coastguard Worker "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
815*08b48e0bSAndroid Build Coastguard Worker "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
816*08b48e0bSAndroid Build Coastguard Worker "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
817*08b48e0bSAndroid Build Coastguard Worker "ASAN_OPTIONS: custom settings for ASAN\n"
818*08b48e0bSAndroid Build Coastguard Worker " (must contain abort_on_error=1 and symbolize=0)\n"
819*08b48e0bSAndroid Build Coastguard Worker "MSAN_OPTIONS: custom settings for MSAN\n"
820*08b48e0bSAndroid Build Coastguard Worker " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
821*08b48e0bSAndroid Build Coastguard Worker "TMPDIR: directory to use for temporary input files\n",
822*08b48e0bSAndroid Build Coastguard Worker argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
823*08b48e0bSAndroid Build Coastguard Worker
824*08b48e0bSAndroid Build Coastguard Worker exit(1);
825*08b48e0bSAndroid Build Coastguard Worker
826*08b48e0bSAndroid Build Coastguard Worker }
827*08b48e0bSAndroid Build Coastguard Worker
828*08b48e0bSAndroid Build Coastguard Worker /* Main entry point */
829*08b48e0bSAndroid Build Coastguard Worker
main(int argc,char ** argv_orig,char ** envp)830*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char **argv_orig, char **envp) {
831*08b48e0bSAndroid Build Coastguard Worker
832*08b48e0bSAndroid Build Coastguard Worker s32 opt;
833*08b48e0bSAndroid Build Coastguard Worker u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
834*08b48e0bSAndroid Build Coastguard Worker char **use_argv;
835*08b48e0bSAndroid Build Coastguard Worker
836*08b48e0bSAndroid Build Coastguard Worker char **argv = argv_cpy_dup(argc, argv_orig);
837*08b48e0bSAndroid Build Coastguard Worker
838*08b48e0bSAndroid Build Coastguard Worker afl_forkserver_t fsrv_var = {0};
839*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_DEBUG")) { debug = 1; }
840*08b48e0bSAndroid Build Coastguard Worker fsrv = &fsrv_var;
841*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_init(fsrv);
842*08b48e0bSAndroid Build Coastguard Worker map_size = get_map_size();
843*08b48e0bSAndroid Build Coastguard Worker fsrv->map_size = map_size;
844*08b48e0bSAndroid Build Coastguard Worker
845*08b48e0bSAndroid Build Coastguard Worker doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
846*08b48e0bSAndroid Build Coastguard Worker
847*08b48e0bSAndroid Build Coastguard Worker SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
848*08b48e0bSAndroid Build Coastguard Worker
849*08b48e0bSAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) {
850*08b48e0bSAndroid Build Coastguard Worker
851*08b48e0bSAndroid Build Coastguard Worker switch (opt) {
852*08b48e0bSAndroid Build Coastguard Worker
853*08b48e0bSAndroid Build Coastguard Worker case 'i':
854*08b48e0bSAndroid Build Coastguard Worker
855*08b48e0bSAndroid Build Coastguard Worker if (in_file) { FATAL("Multiple -i options not supported"); }
856*08b48e0bSAndroid Build Coastguard Worker in_file = optarg;
857*08b48e0bSAndroid Build Coastguard Worker break;
858*08b48e0bSAndroid Build Coastguard Worker
859*08b48e0bSAndroid Build Coastguard Worker case 'o':
860*08b48e0bSAndroid Build Coastguard Worker
861*08b48e0bSAndroid Build Coastguard Worker if (output_file) { FATAL("Multiple -o options not supported"); }
862*08b48e0bSAndroid Build Coastguard Worker output_file = optarg;
863*08b48e0bSAndroid Build Coastguard Worker break;
864*08b48e0bSAndroid Build Coastguard Worker
865*08b48e0bSAndroid Build Coastguard Worker case 'f':
866*08b48e0bSAndroid Build Coastguard Worker
867*08b48e0bSAndroid Build Coastguard Worker if (out_file) { FATAL("Multiple -f options not supported"); }
868*08b48e0bSAndroid Build Coastguard Worker fsrv->use_stdin = 0;
869*08b48e0bSAndroid Build Coastguard Worker out_file = ck_strdup(optarg);
870*08b48e0bSAndroid Build Coastguard Worker break;
871*08b48e0bSAndroid Build Coastguard Worker
872*08b48e0bSAndroid Build Coastguard Worker case 'e':
873*08b48e0bSAndroid Build Coastguard Worker
874*08b48e0bSAndroid Build Coastguard Worker if (edges_only) { FATAL("Multiple -e options not supported"); }
875*08b48e0bSAndroid Build Coastguard Worker if (hang_mode) {
876*08b48e0bSAndroid Build Coastguard Worker
877*08b48e0bSAndroid Build Coastguard Worker FATAL("Edges only and hang mode are mutually exclusive.");
878*08b48e0bSAndroid Build Coastguard Worker
879*08b48e0bSAndroid Build Coastguard Worker }
880*08b48e0bSAndroid Build Coastguard Worker
881*08b48e0bSAndroid Build Coastguard Worker edges_only = 1;
882*08b48e0bSAndroid Build Coastguard Worker break;
883*08b48e0bSAndroid Build Coastguard Worker
884*08b48e0bSAndroid Build Coastguard Worker case 'x':
885*08b48e0bSAndroid Build Coastguard Worker
886*08b48e0bSAndroid Build Coastguard Worker if (exit_crash) { FATAL("Multiple -x options not supported"); }
887*08b48e0bSAndroid Build Coastguard Worker exit_crash = 1;
888*08b48e0bSAndroid Build Coastguard Worker break;
889*08b48e0bSAndroid Build Coastguard Worker
890*08b48e0bSAndroid Build Coastguard Worker case 'm': {
891*08b48e0bSAndroid Build Coastguard Worker
892*08b48e0bSAndroid Build Coastguard Worker u8 suffix = 'M';
893*08b48e0bSAndroid Build Coastguard Worker
894*08b48e0bSAndroid Build Coastguard Worker if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
895*08b48e0bSAndroid Build Coastguard Worker mem_limit_given = 1;
896*08b48e0bSAndroid Build Coastguard Worker
897*08b48e0bSAndroid Build Coastguard Worker if (!optarg) { FATAL("Wrong usage of -m"); }
898*08b48e0bSAndroid Build Coastguard Worker
899*08b48e0bSAndroid Build Coastguard Worker if (!strcmp(optarg, "none")) {
900*08b48e0bSAndroid Build Coastguard Worker
901*08b48e0bSAndroid Build Coastguard Worker fsrv->mem_limit = 0;
902*08b48e0bSAndroid Build Coastguard Worker break;
903*08b48e0bSAndroid Build Coastguard Worker
904*08b48e0bSAndroid Build Coastguard Worker }
905*08b48e0bSAndroid Build Coastguard Worker
906*08b48e0bSAndroid Build Coastguard Worker if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
907*08b48e0bSAndroid Build Coastguard Worker optarg[0] == '-') {
908*08b48e0bSAndroid Build Coastguard Worker
909*08b48e0bSAndroid Build Coastguard Worker FATAL("Bad syntax used for -m");
910*08b48e0bSAndroid Build Coastguard Worker
911*08b48e0bSAndroid Build Coastguard Worker }
912*08b48e0bSAndroid Build Coastguard Worker
913*08b48e0bSAndroid Build Coastguard Worker switch (suffix) {
914*08b48e0bSAndroid Build Coastguard Worker
915*08b48e0bSAndroid Build Coastguard Worker case 'T':
916*08b48e0bSAndroid Build Coastguard Worker fsrv->mem_limit *= 1024 * 1024;
917*08b48e0bSAndroid Build Coastguard Worker break;
918*08b48e0bSAndroid Build Coastguard Worker case 'G':
919*08b48e0bSAndroid Build Coastguard Worker fsrv->mem_limit *= 1024;
920*08b48e0bSAndroid Build Coastguard Worker break;
921*08b48e0bSAndroid Build Coastguard Worker case 'k':
922*08b48e0bSAndroid Build Coastguard Worker fsrv->mem_limit /= 1024;
923*08b48e0bSAndroid Build Coastguard Worker break;
924*08b48e0bSAndroid Build Coastguard Worker case 'M':
925*08b48e0bSAndroid Build Coastguard Worker break;
926*08b48e0bSAndroid Build Coastguard Worker
927*08b48e0bSAndroid Build Coastguard Worker default:
928*08b48e0bSAndroid Build Coastguard Worker FATAL("Unsupported suffix or bad syntax for -m");
929*08b48e0bSAndroid Build Coastguard Worker
930*08b48e0bSAndroid Build Coastguard Worker }
931*08b48e0bSAndroid Build Coastguard Worker
932*08b48e0bSAndroid Build Coastguard Worker if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); }
933*08b48e0bSAndroid Build Coastguard Worker
934*08b48e0bSAndroid Build Coastguard Worker if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) {
935*08b48e0bSAndroid Build Coastguard Worker
936*08b48e0bSAndroid Build Coastguard Worker FATAL("Value of -m out of range on 32-bit systems");
937*08b48e0bSAndroid Build Coastguard Worker
938*08b48e0bSAndroid Build Coastguard Worker }
939*08b48e0bSAndroid Build Coastguard Worker
940*08b48e0bSAndroid Build Coastguard Worker }
941*08b48e0bSAndroid Build Coastguard Worker
942*08b48e0bSAndroid Build Coastguard Worker break;
943*08b48e0bSAndroid Build Coastguard Worker
944*08b48e0bSAndroid Build Coastguard Worker case 't':
945*08b48e0bSAndroid Build Coastguard Worker
946*08b48e0bSAndroid Build Coastguard Worker if (timeout_given) { FATAL("Multiple -t options not supported"); }
947*08b48e0bSAndroid Build Coastguard Worker timeout_given = 1;
948*08b48e0bSAndroid Build Coastguard Worker
949*08b48e0bSAndroid Build Coastguard Worker if (!optarg) { FATAL("Wrong usage of -t"); }
950*08b48e0bSAndroid Build Coastguard Worker
951*08b48e0bSAndroid Build Coastguard Worker fsrv->exec_tmout = atoi(optarg);
952*08b48e0bSAndroid Build Coastguard Worker
953*08b48e0bSAndroid Build Coastguard Worker if (fsrv->exec_tmout < 10 || optarg[0] == '-') {
954*08b48e0bSAndroid Build Coastguard Worker
955*08b48e0bSAndroid Build Coastguard Worker FATAL("Dangerously low value of -t");
956*08b48e0bSAndroid Build Coastguard Worker
957*08b48e0bSAndroid Build Coastguard Worker }
958*08b48e0bSAndroid Build Coastguard Worker
959*08b48e0bSAndroid Build Coastguard Worker break;
960*08b48e0bSAndroid Build Coastguard Worker
961*08b48e0bSAndroid Build Coastguard Worker case 'A': /* CoreSight mode */
962*08b48e0bSAndroid Build Coastguard Worker
963*08b48e0bSAndroid Build Coastguard Worker #if !defined(__aarch64__) || !defined(__linux__)
964*08b48e0bSAndroid Build Coastguard Worker FATAL("-A option is not supported on this platform");
965*08b48e0bSAndroid Build Coastguard Worker #endif
966*08b48e0bSAndroid Build Coastguard Worker
967*08b48e0bSAndroid Build Coastguard Worker if (fsrv->cs_mode) { FATAL("Multiple -A options not supported"); }
968*08b48e0bSAndroid Build Coastguard Worker
969*08b48e0bSAndroid Build Coastguard Worker fsrv->cs_mode = 1;
970*08b48e0bSAndroid Build Coastguard Worker break;
971*08b48e0bSAndroid Build Coastguard Worker
972*08b48e0bSAndroid Build Coastguard Worker case 'O': /* FRIDA mode */
973*08b48e0bSAndroid Build Coastguard Worker
974*08b48e0bSAndroid Build Coastguard Worker if (fsrv->frida_mode) { FATAL("Multiple -O options not supported"); }
975*08b48e0bSAndroid Build Coastguard Worker
976*08b48e0bSAndroid Build Coastguard Worker fsrv->frida_mode = 1;
977*08b48e0bSAndroid Build Coastguard Worker setenv("AFL_FRIDA_INST_SEED", "1", 1);
978*08b48e0bSAndroid Build Coastguard Worker
979*08b48e0bSAndroid Build Coastguard Worker break;
980*08b48e0bSAndroid Build Coastguard Worker
981*08b48e0bSAndroid Build Coastguard Worker case 'Q':
982*08b48e0bSAndroid Build Coastguard Worker
983*08b48e0bSAndroid Build Coastguard Worker if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); }
984*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
985*08b48e0bSAndroid Build Coastguard Worker
986*08b48e0bSAndroid Build Coastguard Worker fsrv->qemu_mode = 1;
987*08b48e0bSAndroid Build Coastguard Worker break;
988*08b48e0bSAndroid Build Coastguard Worker
989*08b48e0bSAndroid Build Coastguard Worker case 'U':
990*08b48e0bSAndroid Build Coastguard Worker
991*08b48e0bSAndroid Build Coastguard Worker if (unicorn_mode) { FATAL("Multiple -Q options not supported"); }
992*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
993*08b48e0bSAndroid Build Coastguard Worker
994*08b48e0bSAndroid Build Coastguard Worker unicorn_mode = 1;
995*08b48e0bSAndroid Build Coastguard Worker break;
996*08b48e0bSAndroid Build Coastguard Worker
997*08b48e0bSAndroid Build Coastguard Worker case 'W': /* Wine+QEMU mode */
998*08b48e0bSAndroid Build Coastguard Worker
999*08b48e0bSAndroid Build Coastguard Worker if (use_wine) { FATAL("Multiple -W options not supported"); }
1000*08b48e0bSAndroid Build Coastguard Worker fsrv->qemu_mode = 1;
1001*08b48e0bSAndroid Build Coastguard Worker use_wine = 1;
1002*08b48e0bSAndroid Build Coastguard Worker
1003*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit_given) { fsrv->mem_limit = 0; }
1004*08b48e0bSAndroid Build Coastguard Worker
1005*08b48e0bSAndroid Build Coastguard Worker break;
1006*08b48e0bSAndroid Build Coastguard Worker
1007*08b48e0bSAndroid Build Coastguard Worker case 'Y': // fallthough
1008*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1009*08b48e0bSAndroid Build Coastguard Worker case 'X': /* NYX mode */
1010*08b48e0bSAndroid Build Coastguard Worker
1011*08b48e0bSAndroid Build Coastguard Worker if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); }
1012*08b48e0bSAndroid Build Coastguard Worker
1013*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_mode = 1;
1014*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_parent = true;
1015*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_standalone = true;
1016*08b48e0bSAndroid Build Coastguard Worker
1017*08b48e0bSAndroid Build Coastguard Worker break;
1018*08b48e0bSAndroid Build Coastguard Worker #else
1019*08b48e0bSAndroid Build Coastguard Worker case 'X':
1020*08b48e0bSAndroid Build Coastguard Worker FATAL("Nyx mode is only availabe on linux...");
1021*08b48e0bSAndroid Build Coastguard Worker break;
1022*08b48e0bSAndroid Build Coastguard Worker #endif
1023*08b48e0bSAndroid Build Coastguard Worker
1024*08b48e0bSAndroid Build Coastguard Worker case 'H': /* Hang Mode */
1025*08b48e0bSAndroid Build Coastguard Worker
1026*08b48e0bSAndroid Build Coastguard Worker /* Minimizes a testcase to the minimum that still times out */
1027*08b48e0bSAndroid Build Coastguard Worker
1028*08b48e0bSAndroid Build Coastguard Worker if (hang_mode) { FATAL("Multipe -H options not supported"); }
1029*08b48e0bSAndroid Build Coastguard Worker if (edges_only) {
1030*08b48e0bSAndroid Build Coastguard Worker
1031*08b48e0bSAndroid Build Coastguard Worker FATAL("Edges only and hang mode are mutually exclusive.");
1032*08b48e0bSAndroid Build Coastguard Worker
1033*08b48e0bSAndroid Build Coastguard Worker }
1034*08b48e0bSAndroid Build Coastguard Worker
1035*08b48e0bSAndroid Build Coastguard Worker hang_mode = 1;
1036*08b48e0bSAndroid Build Coastguard Worker break;
1037*08b48e0bSAndroid Build Coastguard Worker
1038*08b48e0bSAndroid Build Coastguard Worker case 'B': /* load bitmap */
1039*08b48e0bSAndroid Build Coastguard Worker
1040*08b48e0bSAndroid Build Coastguard Worker /* This is a secret undocumented option! It is speculated to be useful
1041*08b48e0bSAndroid Build Coastguard Worker if you have a baseline "boring" input file and another "interesting"
1042*08b48e0bSAndroid Build Coastguard Worker file you want to minimize.
1043*08b48e0bSAndroid Build Coastguard Worker
1044*08b48e0bSAndroid Build Coastguard Worker You can dump a binary bitmap for the boring file using
1045*08b48e0bSAndroid Build Coastguard Worker afl-showmap -b, and then load it into afl-tmin via -B. The minimizer
1046*08b48e0bSAndroid Build Coastguard Worker will then minimize to preserve only the edges that are unique to
1047*08b48e0bSAndroid Build Coastguard Worker the interesting input file, but ignoring everything from the
1048*08b48e0bSAndroid Build Coastguard Worker original map.
1049*08b48e0bSAndroid Build Coastguard Worker
1050*08b48e0bSAndroid Build Coastguard Worker The option may be extended and made more official if it proves
1051*08b48e0bSAndroid Build Coastguard Worker to be useful. */
1052*08b48e0bSAndroid Build Coastguard Worker
1053*08b48e0bSAndroid Build Coastguard Worker if (mask_bitmap) { FATAL("Multiple -B options not supported"); }
1054*08b48e0bSAndroid Build Coastguard Worker mask_bitmap = ck_alloc(map_size);
1055*08b48e0bSAndroid Build Coastguard Worker read_bitmap(optarg, mask_bitmap, map_size);
1056*08b48e0bSAndroid Build Coastguard Worker break;
1057*08b48e0bSAndroid Build Coastguard Worker
1058*08b48e0bSAndroid Build Coastguard Worker case 'h':
1059*08b48e0bSAndroid Build Coastguard Worker usage(argv[0]);
1060*08b48e0bSAndroid Build Coastguard Worker return -1;
1061*08b48e0bSAndroid Build Coastguard Worker break;
1062*08b48e0bSAndroid Build Coastguard Worker
1063*08b48e0bSAndroid Build Coastguard Worker default:
1064*08b48e0bSAndroid Build Coastguard Worker usage(argv[0]);
1065*08b48e0bSAndroid Build Coastguard Worker
1066*08b48e0bSAndroid Build Coastguard Worker }
1067*08b48e0bSAndroid Build Coastguard Worker
1068*08b48e0bSAndroid Build Coastguard Worker }
1069*08b48e0bSAndroid Build Coastguard Worker
1070*08b48e0bSAndroid Build Coastguard Worker if (optind == argc || !in_file || !output_file) { usage(argv[0]); }
1071*08b48e0bSAndroid Build Coastguard Worker
1072*08b48e0bSAndroid Build Coastguard Worker check_environment_vars(envp);
1073*08b48e0bSAndroid Build Coastguard Worker
1074*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_NO_FORKSRV")) { /* if set, use the fauxserver */
1075*08b48e0bSAndroid Build Coastguard Worker fsrv->use_fauxsrv = true;
1076*08b48e0bSAndroid Build Coastguard Worker
1077*08b48e0bSAndroid Build Coastguard Worker }
1078*08b48e0bSAndroid Build Coastguard Worker
1079*08b48e0bSAndroid Build Coastguard Worker setenv("AFL_NO_AUTODICT", "1", 1);
1080*08b48e0bSAndroid Build Coastguard Worker
1081*08b48e0bSAndroid Build Coastguard Worker /* initialize cmplog_mode */
1082*08b48e0bSAndroid Build Coastguard Worker shm.cmplog_mode = 0;
1083*08b48e0bSAndroid Build Coastguard Worker
1084*08b48e0bSAndroid Build Coastguard Worker atexit(at_exit_handler);
1085*08b48e0bSAndroid Build Coastguard Worker setup_signal_handlers();
1086*08b48e0bSAndroid Build Coastguard Worker
1087*08b48e0bSAndroid Build Coastguard Worker set_up_environment(fsrv, argv);
1088*08b48e0bSAndroid Build Coastguard Worker
1089*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1090*08b48e0bSAndroid Build Coastguard Worker if (!fsrv->nyx_mode) {
1091*08b48e0bSAndroid Build Coastguard Worker
1092*08b48e0bSAndroid Build Coastguard Worker fsrv->target_path = find_binary(argv[optind]);
1093*08b48e0bSAndroid Build Coastguard Worker
1094*08b48e0bSAndroid Build Coastguard Worker } else {
1095*08b48e0bSAndroid Build Coastguard Worker
1096*08b48e0bSAndroid Build Coastguard Worker fsrv->target_path = ck_strdup(argv[optind]);
1097*08b48e0bSAndroid Build Coastguard Worker
1098*08b48e0bSAndroid Build Coastguard Worker }
1099*08b48e0bSAndroid Build Coastguard Worker
1100*08b48e0bSAndroid Build Coastguard Worker #else
1101*08b48e0bSAndroid Build Coastguard Worker fsrv->target_path = find_binary(argv[optind]);
1102*08b48e0bSAndroid Build Coastguard Worker #endif
1103*08b48e0bSAndroid Build Coastguard Worker
1104*08b48e0bSAndroid Build Coastguard Worker fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
1105*08b48e0bSAndroid Build Coastguard Worker detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
1106*08b48e0bSAndroid Build Coastguard Worker signal(SIGALRM, kill_child);
1107*08b48e0bSAndroid Build Coastguard Worker
1108*08b48e0bSAndroid Build Coastguard Worker if (fsrv->qemu_mode) {
1109*08b48e0bSAndroid Build Coastguard Worker
1110*08b48e0bSAndroid Build Coastguard Worker if (use_wine) {
1111*08b48e0bSAndroid Build Coastguard Worker
1112*08b48e0bSAndroid Build Coastguard Worker use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
1113*08b48e0bSAndroid Build Coastguard Worker argv + optind);
1114*08b48e0bSAndroid Build Coastguard Worker
1115*08b48e0bSAndroid Build Coastguard Worker } else {
1116*08b48e0bSAndroid Build Coastguard Worker
1117*08b48e0bSAndroid Build Coastguard Worker use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
1118*08b48e0bSAndroid Build Coastguard Worker argv + optind);
1119*08b48e0bSAndroid Build Coastguard Worker
1120*08b48e0bSAndroid Build Coastguard Worker }
1121*08b48e0bSAndroid Build Coastguard Worker
1122*08b48e0bSAndroid Build Coastguard Worker } else if (fsrv->cs_mode) {
1123*08b48e0bSAndroid Build Coastguard Worker
1124*08b48e0bSAndroid Build Coastguard Worker use_argv =
1125*08b48e0bSAndroid Build Coastguard Worker get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind);
1126*08b48e0bSAndroid Build Coastguard Worker
1127*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1128*08b48e0bSAndroid Build Coastguard Worker
1129*08b48e0bSAndroid Build Coastguard Worker } else if (fsrv->nyx_mode) {
1130*08b48e0bSAndroid Build Coastguard Worker
1131*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_id = 0;
1132*08b48e0bSAndroid Build Coastguard Worker
1133*08b48e0bSAndroid Build Coastguard Worker u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so");
1134*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary);
1135*08b48e0bSAndroid Build Coastguard Worker if (fsrv->nyx_handlers == NULL) {
1136*08b48e0bSAndroid Build Coastguard Worker
1137*08b48e0bSAndroid Build Coastguard Worker FATAL("failed to initialize libnyx.so...");
1138*08b48e0bSAndroid Build Coastguard Worker
1139*08b48e0bSAndroid Build Coastguard Worker }
1140*08b48e0bSAndroid Build Coastguard Worker
1141*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_use_tmp_workdir = true;
1142*08b48e0bSAndroid Build Coastguard Worker fsrv->nyx_bind_cpu_id = 0;
1143*08b48e0bSAndroid Build Coastguard Worker
1144*08b48e0bSAndroid Build Coastguard Worker use_argv = argv + optind;
1145*08b48e0bSAndroid Build Coastguard Worker #endif
1146*08b48e0bSAndroid Build Coastguard Worker
1147*08b48e0bSAndroid Build Coastguard Worker } else {
1148*08b48e0bSAndroid Build Coastguard Worker
1149*08b48e0bSAndroid Build Coastguard Worker use_argv = argv + optind;
1150*08b48e0bSAndroid Build Coastguard Worker
1151*08b48e0bSAndroid Build Coastguard Worker }
1152*08b48e0bSAndroid Build Coastguard Worker
1153*08b48e0bSAndroid Build Coastguard Worker exact_mode = !!get_afl_env("AFL_TMIN_EXACT");
1154*08b48e0bSAndroid Build Coastguard Worker
1155*08b48e0bSAndroid Build Coastguard Worker if (hang_mode && exact_mode) {
1156*08b48e0bSAndroid Build Coastguard Worker
1157*08b48e0bSAndroid Build Coastguard Worker SAYF("AFL_TMIN_EXACT won't work for loops in hang mode, ignoring.");
1158*08b48e0bSAndroid Build Coastguard Worker exact_mode = 0;
1159*08b48e0bSAndroid Build Coastguard Worker
1160*08b48e0bSAndroid Build Coastguard Worker }
1161*08b48e0bSAndroid Build Coastguard Worker
1162*08b48e0bSAndroid Build Coastguard Worker SAYF("\n");
1163*08b48e0bSAndroid Build Coastguard Worker
1164*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_FORKSRV_INIT_TMOUT")) {
1165*08b48e0bSAndroid Build Coastguard Worker
1166*08b48e0bSAndroid Build Coastguard Worker s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT"));
1167*08b48e0bSAndroid Build Coastguard Worker if (forksrv_init_tmout < 1) {
1168*08b48e0bSAndroid Build Coastguard Worker
1169*08b48e0bSAndroid Build Coastguard Worker FATAL("Bad value specified for AFL_FORKSRV_INIT_TMOUT");
1170*08b48e0bSAndroid Build Coastguard Worker
1171*08b48e0bSAndroid Build Coastguard Worker }
1172*08b48e0bSAndroid Build Coastguard Worker
1173*08b48e0bSAndroid Build Coastguard Worker fsrv->init_tmout = (u32)forksrv_init_tmout;
1174*08b48e0bSAndroid Build Coastguard Worker
1175*08b48e0bSAndroid Build Coastguard Worker }
1176*08b48e0bSAndroid Build Coastguard Worker
1177*08b48e0bSAndroid Build Coastguard Worker configure_afl_kill_signals(
1178*08b48e0bSAndroid Build Coastguard Worker fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM);
1179*08b48e0bSAndroid Build Coastguard Worker
1180*08b48e0bSAndroid Build Coastguard Worker if (getenv("AFL_CRASH_EXITCODE")) {
1181*08b48e0bSAndroid Build Coastguard Worker
1182*08b48e0bSAndroid Build Coastguard Worker long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
1183*08b48e0bSAndroid Build Coastguard Worker if ((!exitcode && (errno == EINVAL || errno == ERANGE)) ||
1184*08b48e0bSAndroid Build Coastguard Worker exitcode < -127 || exitcode > 128) {
1185*08b48e0bSAndroid Build Coastguard Worker
1186*08b48e0bSAndroid Build Coastguard Worker FATAL("Invalid crash exitcode, expected -127 to 128, but got %s",
1187*08b48e0bSAndroid Build Coastguard Worker getenv("AFL_CRASH_EXITCODE"));
1188*08b48e0bSAndroid Build Coastguard Worker
1189*08b48e0bSAndroid Build Coastguard Worker }
1190*08b48e0bSAndroid Build Coastguard Worker
1191*08b48e0bSAndroid Build Coastguard Worker fsrv->uses_crash_exitcode = true;
1192*08b48e0bSAndroid Build Coastguard Worker // WEXITSTATUS is 8 bit unsigned
1193*08b48e0bSAndroid Build Coastguard Worker fsrv->crash_exitcode = (u8)exitcode;
1194*08b48e0bSAndroid Build Coastguard Worker
1195*08b48e0bSAndroid Build Coastguard Worker }
1196*08b48e0bSAndroid Build Coastguard Worker
1197*08b48e0bSAndroid Build Coastguard Worker shm_fuzz = ck_alloc(sizeof(sharedmem_t));
1198*08b48e0bSAndroid Build Coastguard Worker
1199*08b48e0bSAndroid Build Coastguard Worker /* initialize cmplog_mode */
1200*08b48e0bSAndroid Build Coastguard Worker shm_fuzz->cmplog_mode = 0;
1201*08b48e0bSAndroid Build Coastguard Worker u8 *map = afl_shm_init(shm_fuzz, MAX_FILE + sizeof(u32), 1);
1202*08b48e0bSAndroid Build Coastguard Worker shm_fuzz->shmemfuzz_mode = 1;
1203*08b48e0bSAndroid Build Coastguard Worker if (!map) { FATAL("BUG: Zero return from afl_shm_init."); }
1204*08b48e0bSAndroid Build Coastguard Worker #ifdef USEMMAP
1205*08b48e0bSAndroid Build Coastguard Worker setenv(SHM_FUZZ_ENV_VAR, shm_fuzz->g_shm_file_path, 1);
1206*08b48e0bSAndroid Build Coastguard Worker #else
1207*08b48e0bSAndroid Build Coastguard Worker u8 *shm_str = alloc_printf("%d", shm_fuzz->shm_id);
1208*08b48e0bSAndroid Build Coastguard Worker setenv(SHM_FUZZ_ENV_VAR, shm_str, 1);
1209*08b48e0bSAndroid Build Coastguard Worker ck_free(shm_str);
1210*08b48e0bSAndroid Build Coastguard Worker #endif
1211*08b48e0bSAndroid Build Coastguard Worker fsrv->support_shmem_fuzz = 1;
1212*08b48e0bSAndroid Build Coastguard Worker fsrv->shmem_fuzz_len = (u32 *)map;
1213*08b48e0bSAndroid Build Coastguard Worker fsrv->shmem_fuzz = map + sizeof(u32);
1214*08b48e0bSAndroid Build Coastguard Worker
1215*08b48e0bSAndroid Build Coastguard Worker read_initial_file();
1216*08b48e0bSAndroid Build Coastguard Worker
1217*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
1218*08b48e0bSAndroid Build Coastguard Worker if (!fsrv->nyx_mode) { (void)check_binary_signatures(fsrv->target_path); }
1219*08b48e0bSAndroid Build Coastguard Worker #else
1220*08b48e0bSAndroid Build Coastguard Worker (void)check_binary_signatures(fsrv->target_path);
1221*08b48e0bSAndroid Build Coastguard Worker #endif
1222*08b48e0bSAndroid Build Coastguard Worker
1223*08b48e0bSAndroid Build Coastguard Worker if (!fsrv->qemu_mode && !unicorn_mode) {
1224*08b48e0bSAndroid Build Coastguard Worker
1225*08b48e0bSAndroid Build Coastguard Worker fsrv->map_size = 4194304; // dummy temporary value
1226*08b48e0bSAndroid Build Coastguard Worker u32 new_map_size =
1227*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_get_mapsize(fsrv, use_argv, &stop_soon,
1228*08b48e0bSAndroid Build Coastguard Worker (get_afl_env("AFL_DEBUG_CHILD") ||
1229*08b48e0bSAndroid Build Coastguard Worker get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
1230*08b48e0bSAndroid Build Coastguard Worker ? 1
1231*08b48e0bSAndroid Build Coastguard Worker : 0);
1232*08b48e0bSAndroid Build Coastguard Worker
1233*08b48e0bSAndroid Build Coastguard Worker if (new_map_size) {
1234*08b48e0bSAndroid Build Coastguard Worker
1235*08b48e0bSAndroid Build Coastguard Worker if (map_size < new_map_size ||
1236*08b48e0bSAndroid Build Coastguard Worker (new_map_size > map_size && new_map_size - map_size > MAP_SIZE)) {
1237*08b48e0bSAndroid Build Coastguard Worker
1238*08b48e0bSAndroid Build Coastguard Worker if (!be_quiet)
1239*08b48e0bSAndroid Build Coastguard Worker ACTF("Acquired new map size for target: %u bytes\n", new_map_size);
1240*08b48e0bSAndroid Build Coastguard Worker
1241*08b48e0bSAndroid Build Coastguard Worker afl_shm_deinit(&shm);
1242*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_kill(fsrv);
1243*08b48e0bSAndroid Build Coastguard Worker fsrv->map_size = new_map_size;
1244*08b48e0bSAndroid Build Coastguard Worker fsrv->trace_bits = afl_shm_init(&shm, new_map_size, 0);
1245*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_start(fsrv, use_argv, &stop_soon,
1246*08b48e0bSAndroid Build Coastguard Worker (get_afl_env("AFL_DEBUG_CHILD") ||
1247*08b48e0bSAndroid Build Coastguard Worker get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
1248*08b48e0bSAndroid Build Coastguard Worker ? 1
1249*08b48e0bSAndroid Build Coastguard Worker : 0);
1250*08b48e0bSAndroid Build Coastguard Worker
1251*08b48e0bSAndroid Build Coastguard Worker }
1252*08b48e0bSAndroid Build Coastguard Worker
1253*08b48e0bSAndroid Build Coastguard Worker map_size = new_map_size;
1254*08b48e0bSAndroid Build Coastguard Worker
1255*08b48e0bSAndroid Build Coastguard Worker }
1256*08b48e0bSAndroid Build Coastguard Worker
1257*08b48e0bSAndroid Build Coastguard Worker fsrv->map_size = map_size;
1258*08b48e0bSAndroid Build Coastguard Worker
1259*08b48e0bSAndroid Build Coastguard Worker } else {
1260*08b48e0bSAndroid Build Coastguard Worker
1261*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_start(fsrv, use_argv, &stop_soon,
1262*08b48e0bSAndroid Build Coastguard Worker (get_afl_env("AFL_DEBUG_CHILD") ||
1263*08b48e0bSAndroid Build Coastguard Worker get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
1264*08b48e0bSAndroid Build Coastguard Worker ? 1
1265*08b48e0bSAndroid Build Coastguard Worker : 0);
1266*08b48e0bSAndroid Build Coastguard Worker
1267*08b48e0bSAndroid Build Coastguard Worker }
1268*08b48e0bSAndroid Build Coastguard Worker
1269*08b48e0bSAndroid Build Coastguard Worker if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
1270*08b48e0bSAndroid Build Coastguard Worker shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
1271*08b48e0bSAndroid Build Coastguard Worker
1272*08b48e0bSAndroid Build Coastguard Worker ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
1273*08b48e0bSAndroid Build Coastguard Worker fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
1274*08b48e0bSAndroid Build Coastguard Worker
1275*08b48e0bSAndroid Build Coastguard Worker tmin_run_target(fsrv, in_data, in_len, 1);
1276*08b48e0bSAndroid Build Coastguard Worker
1277*08b48e0bSAndroid Build Coastguard Worker if (hang_mode && !fsrv->last_run_timed_out) {
1278*08b48e0bSAndroid Build Coastguard Worker
1279*08b48e0bSAndroid Build Coastguard Worker FATAL(
1280*08b48e0bSAndroid Build Coastguard Worker "Target binary did not time out but hang minimization mode "
1281*08b48e0bSAndroid Build Coastguard Worker "(-H) was set (-t %u).",
1282*08b48e0bSAndroid Build Coastguard Worker fsrv->exec_tmout);
1283*08b48e0bSAndroid Build Coastguard Worker
1284*08b48e0bSAndroid Build Coastguard Worker }
1285*08b48e0bSAndroid Build Coastguard Worker
1286*08b48e0bSAndroid Build Coastguard Worker if (fsrv->last_run_timed_out && !hang_mode) {
1287*08b48e0bSAndroid Build Coastguard Worker
1288*08b48e0bSAndroid Build Coastguard Worker FATAL(
1289*08b48e0bSAndroid Build Coastguard Worker "Target binary times out (adjusting -t may help). Use -H to minimize a "
1290*08b48e0bSAndroid Build Coastguard Worker "hang.");
1291*08b48e0bSAndroid Build Coastguard Worker
1292*08b48e0bSAndroid Build Coastguard Worker }
1293*08b48e0bSAndroid Build Coastguard Worker
1294*08b48e0bSAndroid Build Coastguard Worker if (hang_mode) {
1295*08b48e0bSAndroid Build Coastguard Worker
1296*08b48e0bSAndroid Build Coastguard Worker OKF("Program hangs as expected, minimizing in " cCYA "hang" cRST " mode.");
1297*08b48e0bSAndroid Build Coastguard Worker
1298*08b48e0bSAndroid Build Coastguard Worker } else if (!crash_mode) {
1299*08b48e0bSAndroid Build Coastguard Worker
1300*08b48e0bSAndroid Build Coastguard Worker OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST
1301*08b48e0bSAndroid Build Coastguard Worker " mode.");
1302*08b48e0bSAndroid Build Coastguard Worker
1303*08b48e0bSAndroid Build Coastguard Worker if (!anything_set(fsrv)) { FATAL("No instrumentation detected."); }
1304*08b48e0bSAndroid Build Coastguard Worker
1305*08b48e0bSAndroid Build Coastguard Worker } else {
1306*08b48e0bSAndroid Build Coastguard Worker
1307*08b48e0bSAndroid Build Coastguard Worker OKF("Program exits with a signal, minimizing in " cMGN "%scrash" cRST
1308*08b48e0bSAndroid Build Coastguard Worker " mode.",
1309*08b48e0bSAndroid Build Coastguard Worker exact_mode ? "EXACT " : "");
1310*08b48e0bSAndroid Build Coastguard Worker
1311*08b48e0bSAndroid Build Coastguard Worker }
1312*08b48e0bSAndroid Build Coastguard Worker
1313*08b48e0bSAndroid Build Coastguard Worker minimize(fsrv);
1314*08b48e0bSAndroid Build Coastguard Worker
1315*08b48e0bSAndroid Build Coastguard Worker ACTF("Writing output to '%s'...", output_file);
1316*08b48e0bSAndroid Build Coastguard Worker
1317*08b48e0bSAndroid Build Coastguard Worker unlink(out_file);
1318*08b48e0bSAndroid Build Coastguard Worker if (out_file) { ck_free(out_file); }
1319*08b48e0bSAndroid Build Coastguard Worker out_file = NULL;
1320*08b48e0bSAndroid Build Coastguard Worker
1321*08b48e0bSAndroid Build Coastguard Worker close(write_to_file(output_file, in_data, in_len));
1322*08b48e0bSAndroid Build Coastguard Worker
1323*08b48e0bSAndroid Build Coastguard Worker OKF("We're done here. Have a nice day!\n");
1324*08b48e0bSAndroid Build Coastguard Worker
1325*08b48e0bSAndroid Build Coastguard Worker remove_shm = 0;
1326*08b48e0bSAndroid Build Coastguard Worker afl_shm_deinit(&shm);
1327*08b48e0bSAndroid Build Coastguard Worker if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
1328*08b48e0bSAndroid Build Coastguard Worker afl_fsrv_deinit(fsrv);
1329*08b48e0bSAndroid Build Coastguard Worker if (fsrv->target_path) { ck_free(fsrv->target_path); }
1330*08b48e0bSAndroid Build Coastguard Worker if (mask_bitmap) { ck_free(mask_bitmap); }
1331*08b48e0bSAndroid Build Coastguard Worker if (in_data) { ck_free(in_data); }
1332*08b48e0bSAndroid Build Coastguard Worker
1333*08b48e0bSAndroid Build Coastguard Worker argv_cpy_free(argv);
1334*08b48e0bSAndroid Build Coastguard Worker
1335*08b48e0bSAndroid Build Coastguard Worker exit(0);
1336*08b48e0bSAndroid Build Coastguard Worker
1337*08b48e0bSAndroid Build Coastguard Worker }
1338*08b48e0bSAndroid Build Coastguard Worker
1339