xref: /aosp_15_r20/external/AFLplusplus/src/afl-fuzz-mutators.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - custom mutators related routines
3*08b48e0bSAndroid Build Coastguard Worker    -------------------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker 
5*08b48e0bSAndroid Build Coastguard Worker    Originally written by Shengtuo Hu
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker    Now maintained by  Marc Heuse <[email protected]>,
8*08b48e0bSAndroid Build Coastguard Worker                         Heiko Eißfeldt <[email protected]> and
9*08b48e0bSAndroid Build Coastguard Worker                         Andrea Fioraldi <[email protected]>
10*08b48e0bSAndroid Build Coastguard Worker                         Dominik Maier <[email protected]>
11*08b48e0bSAndroid Build Coastguard Worker 
12*08b48e0bSAndroid Build Coastguard Worker    Copyright 2016, 2017 Google Inc. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
14*08b48e0bSAndroid Build Coastguard Worker 
15*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
16*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
17*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
18*08b48e0bSAndroid Build Coastguard Worker 
19*08b48e0bSAndroid Build Coastguard Worker      https://www.apache.org/licenses/LICENSE-2.0
20*08b48e0bSAndroid Build Coastguard Worker 
21*08b48e0bSAndroid Build Coastguard Worker    This is the real deal: the program takes an instrumented binary and
22*08b48e0bSAndroid Build Coastguard Worker    attempts a variety of basic fuzzing tricks, paying close attention to
23*08b48e0bSAndroid Build Coastguard Worker    how they affect the execution path.
24*08b48e0bSAndroid Build Coastguard Worker 
25*08b48e0bSAndroid Build Coastguard Worker  */
26*08b48e0bSAndroid Build Coastguard Worker 
27*08b48e0bSAndroid Build Coastguard Worker #include "afl-fuzz.h"
28*08b48e0bSAndroid Build Coastguard Worker 
29*08b48e0bSAndroid Build Coastguard Worker struct custom_mutator *load_custom_mutator(afl_state_t *, const char *);
30*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_PYTHON
31*08b48e0bSAndroid Build Coastguard Worker struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
32*08b48e0bSAndroid Build Coastguard Worker #endif
33*08b48e0bSAndroid Build Coastguard Worker 
run_afl_custom_queue_new_entry(afl_state_t * afl,struct queue_entry * q,u8 * fname,u8 * mother_fname)34*08b48e0bSAndroid Build Coastguard Worker void run_afl_custom_queue_new_entry(afl_state_t *afl, struct queue_entry *q,
35*08b48e0bSAndroid Build Coastguard Worker                                     u8 *fname, u8 *mother_fname) {
36*08b48e0bSAndroid Build Coastguard Worker 
37*08b48e0bSAndroid Build Coastguard Worker   if (afl->custom_mutators_count) {
38*08b48e0bSAndroid Build Coastguard Worker 
39*08b48e0bSAndroid Build Coastguard Worker     u8 updated = 0;
40*08b48e0bSAndroid Build Coastguard Worker 
41*08b48e0bSAndroid Build Coastguard Worker     LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
42*08b48e0bSAndroid Build Coastguard Worker 
43*08b48e0bSAndroid Build Coastguard Worker       if (el->afl_custom_queue_new_entry) {
44*08b48e0bSAndroid Build Coastguard Worker 
45*08b48e0bSAndroid Build Coastguard Worker         if (el->afl_custom_queue_new_entry(el->data, fname, mother_fname)) {
46*08b48e0bSAndroid Build Coastguard Worker 
47*08b48e0bSAndroid Build Coastguard Worker           updated = 1;
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker         }
50*08b48e0bSAndroid Build Coastguard Worker 
51*08b48e0bSAndroid Build Coastguard Worker       }
52*08b48e0bSAndroid Build Coastguard Worker 
53*08b48e0bSAndroid Build Coastguard Worker     });
54*08b48e0bSAndroid Build Coastguard Worker 
55*08b48e0bSAndroid Build Coastguard Worker     if (updated) {
56*08b48e0bSAndroid Build Coastguard Worker 
57*08b48e0bSAndroid Build Coastguard Worker       struct stat st;
58*08b48e0bSAndroid Build Coastguard Worker       if (stat(fname, &st)) { PFATAL("File %s is gone!", fname); }
59*08b48e0bSAndroid Build Coastguard Worker       if (!st.st_size) {
60*08b48e0bSAndroid Build Coastguard Worker 
61*08b48e0bSAndroid Build Coastguard Worker         FATAL("File %s became empty in custom mutator!", fname);
62*08b48e0bSAndroid Build Coastguard Worker 
63*08b48e0bSAndroid Build Coastguard Worker       }
64*08b48e0bSAndroid Build Coastguard Worker 
65*08b48e0bSAndroid Build Coastguard Worker       q->len = st.st_size;
66*08b48e0bSAndroid Build Coastguard Worker 
67*08b48e0bSAndroid Build Coastguard Worker     }
68*08b48e0bSAndroid Build Coastguard Worker 
69*08b48e0bSAndroid Build Coastguard Worker   }
70*08b48e0bSAndroid Build Coastguard Worker 
71*08b48e0bSAndroid Build Coastguard Worker }
72*08b48e0bSAndroid Build Coastguard Worker 
setup_custom_mutators(afl_state_t * afl)73*08b48e0bSAndroid Build Coastguard Worker void setup_custom_mutators(afl_state_t *afl) {
74*08b48e0bSAndroid Build Coastguard Worker 
75*08b48e0bSAndroid Build Coastguard Worker   /* Try mutator library first */
76*08b48e0bSAndroid Build Coastguard Worker   struct custom_mutator *mutator;
77*08b48e0bSAndroid Build Coastguard Worker   u8                    *fn = afl->afl_env.afl_custom_mutator_library;
78*08b48e0bSAndroid Build Coastguard Worker   u32                    prev_mutator_count = 0;
79*08b48e0bSAndroid Build Coastguard Worker 
80*08b48e0bSAndroid Build Coastguard Worker   if (fn) {
81*08b48e0bSAndroid Build Coastguard Worker 
82*08b48e0bSAndroid Build Coastguard Worker     if (afl->limit_time_sig && afl->limit_time_sig != -1)
83*08b48e0bSAndroid Build Coastguard Worker       FATAL(
84*08b48e0bSAndroid Build Coastguard Worker           "MOpt and custom mutator are mutually exclusive. We accept pull "
85*08b48e0bSAndroid Build Coastguard Worker           "requests that integrates MOpt with the optional mutators "
86*08b48e0bSAndroid Build Coastguard Worker           "(custom/redqueen/...).");
87*08b48e0bSAndroid Build Coastguard Worker 
88*08b48e0bSAndroid Build Coastguard Worker     u8 *fn_token = (u8 *)strsep((char **)&fn, ";:,");
89*08b48e0bSAndroid Build Coastguard Worker 
90*08b48e0bSAndroid Build Coastguard Worker     if (likely(!fn_token)) {
91*08b48e0bSAndroid Build Coastguard Worker 
92*08b48e0bSAndroid Build Coastguard Worker       mutator = load_custom_mutator(afl, fn);
93*08b48e0bSAndroid Build Coastguard Worker       list_append(&afl->custom_mutator_list, mutator);
94*08b48e0bSAndroid Build Coastguard Worker       afl->custom_mutators_count++;
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker     } else {
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker       while (fn_token) {
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker         if (*fn_token) {  // strsep can be empty if ";;"
101*08b48e0bSAndroid Build Coastguard Worker 
102*08b48e0bSAndroid Build Coastguard Worker           if (afl->not_on_tty && afl->debug)
103*08b48e0bSAndroid Build Coastguard Worker             SAYF("[Custom] Processing: %s\n", fn_token);
104*08b48e0bSAndroid Build Coastguard Worker           prev_mutator_count = afl->custom_mutators_count;
105*08b48e0bSAndroid Build Coastguard Worker           mutator = load_custom_mutator(afl, fn_token);
106*08b48e0bSAndroid Build Coastguard Worker           list_append(&afl->custom_mutator_list, mutator);
107*08b48e0bSAndroid Build Coastguard Worker           afl->custom_mutators_count++;
108*08b48e0bSAndroid Build Coastguard Worker           if (prev_mutator_count > afl->custom_mutators_count)
109*08b48e0bSAndroid Build Coastguard Worker             FATAL("Maximum Custom Mutator count reached.");
110*08b48e0bSAndroid Build Coastguard Worker           fn_token = (u8 *)strsep((char **)&fn, ";:,");
111*08b48e0bSAndroid Build Coastguard Worker 
112*08b48e0bSAndroid Build Coastguard Worker         }
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker       }
115*08b48e0bSAndroid Build Coastguard Worker 
116*08b48e0bSAndroid Build Coastguard Worker     }
117*08b48e0bSAndroid Build Coastguard Worker 
118*08b48e0bSAndroid Build Coastguard Worker   }
119*08b48e0bSAndroid Build Coastguard Worker 
120*08b48e0bSAndroid Build Coastguard Worker   /* Try Python module */
121*08b48e0bSAndroid Build Coastguard Worker #ifdef USE_PYTHON
122*08b48e0bSAndroid Build Coastguard Worker   u8 *module_name = afl->afl_env.afl_python_module;
123*08b48e0bSAndroid Build Coastguard Worker 
124*08b48e0bSAndroid Build Coastguard Worker   if (module_name) {
125*08b48e0bSAndroid Build Coastguard Worker 
126*08b48e0bSAndroid Build Coastguard Worker     if (afl->limit_time_sig) {
127*08b48e0bSAndroid Build Coastguard Worker 
128*08b48e0bSAndroid Build Coastguard Worker       FATAL(
129*08b48e0bSAndroid Build Coastguard Worker           "MOpt and Python mutator are mutually exclusive. We accept pull "
130*08b48e0bSAndroid Build Coastguard Worker           "requests that integrates MOpt with the optional mutators "
131*08b48e0bSAndroid Build Coastguard Worker           "(custom/redqueen/...).");
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker     }
134*08b48e0bSAndroid Build Coastguard Worker 
135*08b48e0bSAndroid Build Coastguard Worker     struct custom_mutator *m = load_custom_mutator_py(afl, module_name);
136*08b48e0bSAndroid Build Coastguard Worker     afl->custom_mutators_count++;
137*08b48e0bSAndroid Build Coastguard Worker     list_append(&afl->custom_mutator_list, m);
138*08b48e0bSAndroid Build Coastguard Worker 
139*08b48e0bSAndroid Build Coastguard Worker   }
140*08b48e0bSAndroid Build Coastguard Worker 
141*08b48e0bSAndroid Build Coastguard Worker #else
142*08b48e0bSAndroid Build Coastguard Worker   if (afl->afl_env.afl_python_module) {
143*08b48e0bSAndroid Build Coastguard Worker 
144*08b48e0bSAndroid Build Coastguard Worker     FATAL("Your AFL binary was built without Python support");
145*08b48e0bSAndroid Build Coastguard Worker 
146*08b48e0bSAndroid Build Coastguard Worker   }
147*08b48e0bSAndroid Build Coastguard Worker 
148*08b48e0bSAndroid Build Coastguard Worker #endif
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker }
151*08b48e0bSAndroid Build Coastguard Worker 
destroy_custom_mutators(afl_state_t * afl)152*08b48e0bSAndroid Build Coastguard Worker void destroy_custom_mutators(afl_state_t *afl) {
153*08b48e0bSAndroid Build Coastguard Worker 
154*08b48e0bSAndroid Build Coastguard Worker   if (afl->custom_mutators_count) {
155*08b48e0bSAndroid Build Coastguard Worker 
156*08b48e0bSAndroid Build Coastguard Worker     LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
157*08b48e0bSAndroid Build Coastguard Worker 
158*08b48e0bSAndroid Build Coastguard Worker       if (!el->data) { FATAL("Deintializing NULL mutator"); }
159*08b48e0bSAndroid Build Coastguard Worker       if (el->afl_custom_deinit) el->afl_custom_deinit(el->data);
160*08b48e0bSAndroid Build Coastguard Worker       if (el->dh) dlclose(el->dh);
161*08b48e0bSAndroid Build Coastguard Worker 
162*08b48e0bSAndroid Build Coastguard Worker       if (el->post_process_buf) {
163*08b48e0bSAndroid Build Coastguard Worker 
164*08b48e0bSAndroid Build Coastguard Worker         afl_free(el->post_process_buf);
165*08b48e0bSAndroid Build Coastguard Worker         el->post_process_buf = NULL;
166*08b48e0bSAndroid Build Coastguard Worker 
167*08b48e0bSAndroid Build Coastguard Worker       }
168*08b48e0bSAndroid Build Coastguard Worker 
169*08b48e0bSAndroid Build Coastguard Worker       ck_free(el);
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker     });
172*08b48e0bSAndroid Build Coastguard Worker 
173*08b48e0bSAndroid Build Coastguard Worker   }
174*08b48e0bSAndroid Build Coastguard Worker 
175*08b48e0bSAndroid Build Coastguard Worker }
176*08b48e0bSAndroid Build Coastguard Worker 
load_custom_mutator(afl_state_t * afl,const char * fn)177*08b48e0bSAndroid Build Coastguard Worker struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
178*08b48e0bSAndroid Build Coastguard Worker 
179*08b48e0bSAndroid Build Coastguard Worker   void                  *dh;
180*08b48e0bSAndroid Build Coastguard Worker   struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
181*08b48e0bSAndroid Build Coastguard Worker 
182*08b48e0bSAndroid Build Coastguard Worker   if (memchr(fn, '/', strlen(fn))) {
183*08b48e0bSAndroid Build Coastguard Worker 
184*08b48e0bSAndroid Build Coastguard Worker     mutator->name_short = strdup(strrchr(fn, '/') + 1);
185*08b48e0bSAndroid Build Coastguard Worker 
186*08b48e0bSAndroid Build Coastguard Worker   } else {
187*08b48e0bSAndroid Build Coastguard Worker 
188*08b48e0bSAndroid Build Coastguard Worker     mutator->name_short = strdup(fn);
189*08b48e0bSAndroid Build Coastguard Worker 
190*08b48e0bSAndroid Build Coastguard Worker   }
191*08b48e0bSAndroid Build Coastguard Worker 
192*08b48e0bSAndroid Build Coastguard Worker   if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
193*08b48e0bSAndroid Build Coastguard Worker 
194*08b48e0bSAndroid Build Coastguard Worker   mutator->name = fn;
195*08b48e0bSAndroid Build Coastguard Worker   ACTF("Loading custom mutator library from '%s'...", fn);
196*08b48e0bSAndroid Build Coastguard Worker 
197*08b48e0bSAndroid Build Coastguard Worker   dh = dlopen(fn, RTLD_NOW);
198*08b48e0bSAndroid Build Coastguard Worker   if (!dh) FATAL("%s", dlerror());
199*08b48e0bSAndroid Build Coastguard Worker   mutator->dh = dh;
200*08b48e0bSAndroid Build Coastguard Worker 
201*08b48e0bSAndroid Build Coastguard Worker   /* Mutator */
202*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_init", optional for backward compatibility */
203*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
204*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_init) {
205*08b48e0bSAndroid Build Coastguard Worker 
206*08b48e0bSAndroid Build Coastguard Worker     FATAL("Symbol 'afl_custom_init' not found.");
207*08b48e0bSAndroid Build Coastguard Worker 
208*08b48e0bSAndroid Build Coastguard Worker   }
209*08b48e0bSAndroid Build Coastguard Worker 
210*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_fuzz" or "afl_custom_mutator", required */
211*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
212*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_fuzz) {
213*08b48e0bSAndroid Build Coastguard Worker 
214*08b48e0bSAndroid Build Coastguard Worker     /* Try "afl_custom_mutator" for backward compatibility */
215*08b48e0bSAndroid Build Coastguard Worker     WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
216*08b48e0bSAndroid Build Coastguard Worker 
217*08b48e0bSAndroid Build Coastguard Worker     mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
218*08b48e0bSAndroid Build Coastguard Worker     if (!mutator->afl_custom_fuzz) {
219*08b48e0bSAndroid Build Coastguard Worker 
220*08b48e0bSAndroid Build Coastguard Worker       WARNF("Symbol 'afl_custom_mutator' not found.");
221*08b48e0bSAndroid Build Coastguard Worker 
222*08b48e0bSAndroid Build Coastguard Worker     } else {
223*08b48e0bSAndroid Build Coastguard Worker 
224*08b48e0bSAndroid Build Coastguard Worker       OKF("Found 'afl_custom_mutator'.");
225*08b48e0bSAndroid Build Coastguard Worker 
226*08b48e0bSAndroid Build Coastguard Worker     }
227*08b48e0bSAndroid Build Coastguard Worker 
228*08b48e0bSAndroid Build Coastguard Worker   } else {
229*08b48e0bSAndroid Build Coastguard Worker 
230*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_mutator'.");
231*08b48e0bSAndroid Build Coastguard Worker 
232*08b48e0bSAndroid Build Coastguard Worker   }
233*08b48e0bSAndroid Build Coastguard Worker 
234*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_introspection", optional */
235*08b48e0bSAndroid Build Coastguard Worker #ifdef INTROSPECTION
236*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection");
237*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_introspection) {
238*08b48e0bSAndroid Build Coastguard Worker 
239*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_introspection' not found.");
240*08b48e0bSAndroid Build Coastguard Worker 
241*08b48e0bSAndroid Build Coastguard Worker   } else {
242*08b48e0bSAndroid Build Coastguard Worker 
243*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_introspection'.");
244*08b48e0bSAndroid Build Coastguard Worker 
245*08b48e0bSAndroid Build Coastguard Worker   }
246*08b48e0bSAndroid Build Coastguard Worker 
247*08b48e0bSAndroid Build Coastguard Worker #endif
248*08b48e0bSAndroid Build Coastguard Worker 
249*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_fuzz_count", optional */
250*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count");
251*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_fuzz_count) {
252*08b48e0bSAndroid Build Coastguard Worker 
253*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_fuzz_count' not found.");
254*08b48e0bSAndroid Build Coastguard Worker 
255*08b48e0bSAndroid Build Coastguard Worker   } else {
256*08b48e0bSAndroid Build Coastguard Worker 
257*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_fuzz_count'.");
258*08b48e0bSAndroid Build Coastguard Worker 
259*08b48e0bSAndroid Build Coastguard Worker   }
260*08b48e0bSAndroid Build Coastguard Worker 
261*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_deinit", optional for backward compatibility */
262*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
263*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_deinit) {
264*08b48e0bSAndroid Build Coastguard Worker 
265*08b48e0bSAndroid Build Coastguard Worker     FATAL("Symbol 'afl_custom_deinit' not found.");
266*08b48e0bSAndroid Build Coastguard Worker 
267*08b48e0bSAndroid Build Coastguard Worker   }
268*08b48e0bSAndroid Build Coastguard Worker 
269*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_post_process", optional */
270*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_post_process = dlsym(dh, "afl_custom_post_process");
271*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_post_process) {
272*08b48e0bSAndroid Build Coastguard Worker 
273*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_post_process' not found.");
274*08b48e0bSAndroid Build Coastguard Worker 
275*08b48e0bSAndroid Build Coastguard Worker   } else {
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_post_process'.");
278*08b48e0bSAndroid Build Coastguard Worker 
279*08b48e0bSAndroid Build Coastguard Worker   }
280*08b48e0bSAndroid Build Coastguard Worker 
281*08b48e0bSAndroid Build Coastguard Worker   u8 notrim = 0;
282*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_init_trim", optional */
283*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
284*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_init_trim) {
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker     notrim = 1;
287*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_init_trim' not found.");
288*08b48e0bSAndroid Build Coastguard Worker 
289*08b48e0bSAndroid Build Coastguard Worker   } else {
290*08b48e0bSAndroid Build Coastguard Worker 
291*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_init_trim'.");
292*08b48e0bSAndroid Build Coastguard Worker 
293*08b48e0bSAndroid Build Coastguard Worker   }
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_trim", optional */
296*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
297*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_trim) {
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker     notrim = 1;
300*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_trim' not found.");
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker   } else {
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_trim'.");
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker   }
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_post_trim", optional */
309*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
310*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_post_trim) {
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker     notrim = 1;
313*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_post_trim' not found.");
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker   } else {
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_post_trim'.");
318*08b48e0bSAndroid Build Coastguard Worker 
319*08b48e0bSAndroid Build Coastguard Worker   }
320*08b48e0bSAndroid Build Coastguard Worker 
321*08b48e0bSAndroid Build Coastguard Worker   if (notrim) {
322*08b48e0bSAndroid Build Coastguard Worker 
323*08b48e0bSAndroid Build Coastguard Worker     if (mutator->afl_custom_init_trim || mutator->afl_custom_trim ||
324*08b48e0bSAndroid Build Coastguard Worker         mutator->afl_custom_post_trim) {
325*08b48e0bSAndroid Build Coastguard Worker 
326*08b48e0bSAndroid Build Coastguard Worker       WARNF(
327*08b48e0bSAndroid Build Coastguard Worker           "Custom mutator does not implement all three trim APIs, standard "
328*08b48e0bSAndroid Build Coastguard Worker           "trimming will be used.");
329*08b48e0bSAndroid Build Coastguard Worker 
330*08b48e0bSAndroid Build Coastguard Worker     }
331*08b48e0bSAndroid Build Coastguard Worker 
332*08b48e0bSAndroid Build Coastguard Worker     mutator->afl_custom_init_trim = NULL;
333*08b48e0bSAndroid Build Coastguard Worker     mutator->afl_custom_trim = NULL;
334*08b48e0bSAndroid Build Coastguard Worker     mutator->afl_custom_post_trim = NULL;
335*08b48e0bSAndroid Build Coastguard Worker 
336*08b48e0bSAndroid Build Coastguard Worker   }
337*08b48e0bSAndroid Build Coastguard Worker 
338*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_havoc_mutation", optional */
339*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
340*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_havoc_mutation) {
341*08b48e0bSAndroid Build Coastguard Worker 
342*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_havoc_mutation' not found.");
343*08b48e0bSAndroid Build Coastguard Worker 
344*08b48e0bSAndroid Build Coastguard Worker   } else {
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_havoc_mutation'.");
347*08b48e0bSAndroid Build Coastguard Worker 
348*08b48e0bSAndroid Build Coastguard Worker   }
349*08b48e0bSAndroid Build Coastguard Worker 
350*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_havoc_mutation", optional */
351*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_havoc_mutation_probability =
352*08b48e0bSAndroid Build Coastguard Worker       dlsym(dh, "afl_custom_havoc_mutation_probability");
353*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_havoc_mutation_probability) {
354*08b48e0bSAndroid Build Coastguard Worker 
355*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found.");
356*08b48e0bSAndroid Build Coastguard Worker 
357*08b48e0bSAndroid Build Coastguard Worker   } else {
358*08b48e0bSAndroid Build Coastguard Worker 
359*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_havoc_mutation_probability'.");
360*08b48e0bSAndroid Build Coastguard Worker 
361*08b48e0bSAndroid Build Coastguard Worker   }
362*08b48e0bSAndroid Build Coastguard Worker 
363*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_queue_get", optional */
364*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
365*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_queue_get) {
366*08b48e0bSAndroid Build Coastguard Worker 
367*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_queue_get' not found.");
368*08b48e0bSAndroid Build Coastguard Worker 
369*08b48e0bSAndroid Build Coastguard Worker   } else {
370*08b48e0bSAndroid Build Coastguard Worker 
371*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_queue_get'.");
372*08b48e0bSAndroid Build Coastguard Worker 
373*08b48e0bSAndroid Build Coastguard Worker   }
374*08b48e0bSAndroid Build Coastguard Worker 
375*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_splice_optout", optional, never called */
376*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_splice_optout = dlsym(dh, "afl_custom_splice_optout");
377*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_splice_optout) {
378*08b48e0bSAndroid Build Coastguard Worker 
379*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_splice_optout' not found.");
380*08b48e0bSAndroid Build Coastguard Worker 
381*08b48e0bSAndroid Build Coastguard Worker   } else {
382*08b48e0bSAndroid Build Coastguard Worker 
383*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_splice_optout'.");
384*08b48e0bSAndroid Build Coastguard Worker     afl->custom_splice_optout = 1;
385*08b48e0bSAndroid Build Coastguard Worker 
386*08b48e0bSAndroid Build Coastguard Worker   }
387*08b48e0bSAndroid Build Coastguard Worker 
388*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_fuzz_send", optional */
389*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send");
390*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_fuzz_send) {
391*08b48e0bSAndroid Build Coastguard Worker 
392*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_fuzz_send' not found.");
393*08b48e0bSAndroid Build Coastguard Worker 
394*08b48e0bSAndroid Build Coastguard Worker   } else {
395*08b48e0bSAndroid Build Coastguard Worker 
396*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_fuzz_send'.");
397*08b48e0bSAndroid Build Coastguard Worker 
398*08b48e0bSAndroid Build Coastguard Worker   }
399*08b48e0bSAndroid Build Coastguard Worker 
400*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_post_run", optional */
401*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_post_run = dlsym(dh, "afl_custom_post_run");
402*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_post_run) {
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_post_run' not found.");
405*08b48e0bSAndroid Build Coastguard Worker 
406*08b48e0bSAndroid Build Coastguard Worker   } else {
407*08b48e0bSAndroid Build Coastguard Worker 
408*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_post_run'.");
409*08b48e0bSAndroid Build Coastguard Worker 
410*08b48e0bSAndroid Build Coastguard Worker   }
411*08b48e0bSAndroid Build Coastguard Worker 
412*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_queue_new_entry", optional */
413*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
414*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_queue_new_entry) {
415*08b48e0bSAndroid Build Coastguard Worker 
416*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_queue_new_entry' not found");
417*08b48e0bSAndroid Build Coastguard Worker 
418*08b48e0bSAndroid Build Coastguard Worker   } else {
419*08b48e0bSAndroid Build Coastguard Worker 
420*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_queue_new_entry'.");
421*08b48e0bSAndroid Build Coastguard Worker 
422*08b48e0bSAndroid Build Coastguard Worker   }
423*08b48e0bSAndroid Build Coastguard Worker 
424*08b48e0bSAndroid Build Coastguard Worker   /* "afl_custom_describe", optional */
425*08b48e0bSAndroid Build Coastguard Worker   mutator->afl_custom_describe = dlsym(dh, "afl_custom_describe");
426*08b48e0bSAndroid Build Coastguard Worker   if (!mutator->afl_custom_describe) {
427*08b48e0bSAndroid Build Coastguard Worker 
428*08b48e0bSAndroid Build Coastguard Worker     ACTF("optional symbol 'afl_custom_describe' not found.");
429*08b48e0bSAndroid Build Coastguard Worker 
430*08b48e0bSAndroid Build Coastguard Worker   } else {
431*08b48e0bSAndroid Build Coastguard Worker 
432*08b48e0bSAndroid Build Coastguard Worker     OKF("Found 'afl_custom_describe'.");
433*08b48e0bSAndroid Build Coastguard Worker 
434*08b48e0bSAndroid Build Coastguard Worker   }
435*08b48e0bSAndroid Build Coastguard Worker 
436*08b48e0bSAndroid Build Coastguard Worker   OKF("Custom mutator '%s' installed successfully.", fn);
437*08b48e0bSAndroid Build Coastguard Worker 
438*08b48e0bSAndroid Build Coastguard Worker   /* Initialize the custom mutator */
439*08b48e0bSAndroid Build Coastguard Worker   if (mutator->afl_custom_init) {
440*08b48e0bSAndroid Build Coastguard Worker 
441*08b48e0bSAndroid Build Coastguard Worker     mutator->data = mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
442*08b48e0bSAndroid Build Coastguard Worker 
443*08b48e0bSAndroid Build Coastguard Worker   }
444*08b48e0bSAndroid Build Coastguard Worker 
445*08b48e0bSAndroid Build Coastguard Worker   mutator->stacked_custom = (mutator && mutator->afl_custom_havoc_mutation);
446*08b48e0bSAndroid Build Coastguard Worker   mutator->stacked_custom_prob =
447*08b48e0bSAndroid Build Coastguard Worker       6;  // like one of the default mutations in havoc
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker   return mutator;
450*08b48e0bSAndroid Build Coastguard Worker 
451*08b48e0bSAndroid Build Coastguard Worker }
452*08b48e0bSAndroid Build Coastguard Worker 
trim_case_custom(afl_state_t * afl,struct queue_entry * q,u8 * in_buf,struct custom_mutator * mutator)453*08b48e0bSAndroid Build Coastguard Worker u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
454*08b48e0bSAndroid Build Coastguard Worker                     struct custom_mutator *mutator) {
455*08b48e0bSAndroid Build Coastguard Worker 
456*08b48e0bSAndroid Build Coastguard Worker   u8  fault = 0;
457*08b48e0bSAndroid Build Coastguard Worker   u32 trim_exec = 0;
458*08b48e0bSAndroid Build Coastguard Worker   u32 orig_len = q->len;
459*08b48e0bSAndroid Build Coastguard Worker   u32 out_len = 0;
460*08b48e0bSAndroid Build Coastguard Worker   u8 *out_buf = NULL;
461*08b48e0bSAndroid Build Coastguard Worker 
462*08b48e0bSAndroid Build Coastguard Worker   u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
463*08b48e0bSAndroid Build Coastguard Worker 
464*08b48e0bSAndroid Build Coastguard Worker   afl->stage_name = afl->stage_name_buf;
465*08b48e0bSAndroid Build Coastguard Worker   afl->bytes_trim_in += q->len;
466*08b48e0bSAndroid Build Coastguard Worker 
467*08b48e0bSAndroid Build Coastguard Worker   /* Initialize trimming in the custom mutator */
468*08b48e0bSAndroid Build Coastguard Worker   afl->stage_cur = 0;
469*08b48e0bSAndroid Build Coastguard Worker   s32 retval = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len);
470*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(retval) < 0) {
471*08b48e0bSAndroid Build Coastguard Worker 
472*08b48e0bSAndroid Build Coastguard Worker     FATAL("custom_init_trim error ret: %d", retval);
473*08b48e0bSAndroid Build Coastguard Worker 
474*08b48e0bSAndroid Build Coastguard Worker   } else {
475*08b48e0bSAndroid Build Coastguard Worker 
476*08b48e0bSAndroid Build Coastguard Worker     afl->stage_max = retval;
477*08b48e0bSAndroid Build Coastguard Worker 
478*08b48e0bSAndroid Build Coastguard Worker   }
479*08b48e0bSAndroid Build Coastguard Worker 
480*08b48e0bSAndroid Build Coastguard Worker   if (afl->not_on_tty && afl->debug) {
481*08b48e0bSAndroid Build Coastguard Worker 
482*08b48e0bSAndroid Build Coastguard Worker     SAYF("[Custom Trimming] START: Max %u iterations, %u bytes", afl->stage_max,
483*08b48e0bSAndroid Build Coastguard Worker          q->len);
484*08b48e0bSAndroid Build Coastguard Worker 
485*08b48e0bSAndroid Build Coastguard Worker   }
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker   while (afl->stage_cur < afl->stage_max) {
488*08b48e0bSAndroid Build Coastguard Worker 
489*08b48e0bSAndroid Build Coastguard Worker     u8 *retbuf = NULL;
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker     sprintf(afl->stage_name_buf, "ptrim %s",
492*08b48e0bSAndroid Build Coastguard Worker             u_stringify_int(val_buf, trim_exec));
493*08b48e0bSAndroid Build Coastguard Worker 
494*08b48e0bSAndroid Build Coastguard Worker     u64 cksum;
495*08b48e0bSAndroid Build Coastguard Worker 
496*08b48e0bSAndroid Build Coastguard Worker     size_t retlen = mutator->afl_custom_trim(mutator->data, &retbuf);
497*08b48e0bSAndroid Build Coastguard Worker 
498*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(!retbuf)) {
499*08b48e0bSAndroid Build Coastguard Worker 
500*08b48e0bSAndroid Build Coastguard Worker       FATAL("custom_trim failed (ret %zu)", retlen);
501*08b48e0bSAndroid Build Coastguard Worker 
502*08b48e0bSAndroid Build Coastguard Worker     } else if (unlikely(retlen > orig_len)) {
503*08b48e0bSAndroid Build Coastguard Worker 
504*08b48e0bSAndroid Build Coastguard Worker       /* Do not exit the fuzzer, even if the trimmed data returned by the custom
505*08b48e0bSAndroid Build Coastguard Worker          mutator is larger than the original data. For some use cases, like the
506*08b48e0bSAndroid Build Coastguard Worker          grammar mutator, the definition of "size" may have different meanings.
507*08b48e0bSAndroid Build Coastguard Worker          For example, the trimming function in a grammar mutator aims at
508*08b48e0bSAndroid Build Coastguard Worker          reducing the objects in a grammar structure, but does not guarantee to
509*08b48e0bSAndroid Build Coastguard Worker          generate a smaller binary buffer.
510*08b48e0bSAndroid Build Coastguard Worker 
511*08b48e0bSAndroid Build Coastguard Worker          Thus, we allow the custom mutator to generate the trimmed data that is
512*08b48e0bSAndroid Build Coastguard Worker          larger than the original data. */
513*08b48e0bSAndroid Build Coastguard Worker 
514*08b48e0bSAndroid Build Coastguard Worker       if (afl->not_on_tty && afl->debug) {
515*08b48e0bSAndroid Build Coastguard Worker 
516*08b48e0bSAndroid Build Coastguard Worker         WARNF(
517*08b48e0bSAndroid Build Coastguard Worker             "Trimmed data returned by custom mutator is larger than original "
518*08b48e0bSAndroid Build Coastguard Worker             "data");
519*08b48e0bSAndroid Build Coastguard Worker 
520*08b48e0bSAndroid Build Coastguard Worker       }
521*08b48e0bSAndroid Build Coastguard Worker 
522*08b48e0bSAndroid Build Coastguard Worker     } else if (unlikely(retlen == 0)) {
523*08b48e0bSAndroid Build Coastguard Worker 
524*08b48e0bSAndroid Build Coastguard Worker       /* Do not run the empty test case on the target. To keep the custom
525*08b48e0bSAndroid Build Coastguard Worker          trimming function running, we simply treat the empty test case as an
526*08b48e0bSAndroid Build Coastguard Worker          unsuccessful trimming and skip it, instead of aborting the trimming. */
527*08b48e0bSAndroid Build Coastguard Worker 
528*08b48e0bSAndroid Build Coastguard Worker       ++afl->trim_execs;
529*08b48e0bSAndroid Build Coastguard Worker 
530*08b48e0bSAndroid Build Coastguard Worker     }
531*08b48e0bSAndroid Build Coastguard Worker 
532*08b48e0bSAndroid Build Coastguard Worker     if (likely(retlen)) {
533*08b48e0bSAndroid Build Coastguard Worker 
534*08b48e0bSAndroid Build Coastguard Worker       retlen = write_to_testcase(afl, (void **)&retbuf, retlen, 0);
535*08b48e0bSAndroid Build Coastguard Worker 
536*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(!retlen)) {
537*08b48e0bSAndroid Build Coastguard Worker 
538*08b48e0bSAndroid Build Coastguard Worker         ++afl->trim_execs;
539*08b48e0bSAndroid Build Coastguard Worker 
540*08b48e0bSAndroid Build Coastguard Worker       } else {
541*08b48e0bSAndroid Build Coastguard Worker 
542*08b48e0bSAndroid Build Coastguard Worker         fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
543*08b48e0bSAndroid Build Coastguard Worker         ++afl->trim_execs;
544*08b48e0bSAndroid Build Coastguard Worker 
545*08b48e0bSAndroid Build Coastguard Worker         if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
546*08b48e0bSAndroid Build Coastguard Worker 
547*08b48e0bSAndroid Build Coastguard Worker         classify_counts(&afl->fsrv);
548*08b48e0bSAndroid Build Coastguard Worker         cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
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 
554*08b48e0bSAndroid Build Coastguard Worker     if (likely(retlen && cksum == q->exec_cksum)) {
555*08b48e0bSAndroid Build Coastguard Worker 
556*08b48e0bSAndroid Build Coastguard Worker       /* Let's save a clean trace, which will be needed by
557*08b48e0bSAndroid Build Coastguard Worker          update_bitmap_score once we're done with the trimming stuff.
558*08b48e0bSAndroid Build Coastguard Worker          Use out_buf NULL check to make this only happen once per trim. */
559*08b48e0bSAndroid Build Coastguard Worker 
560*08b48e0bSAndroid Build Coastguard Worker       if (!out_buf) {
561*08b48e0bSAndroid Build Coastguard Worker 
562*08b48e0bSAndroid Build Coastguard Worker         memcpy(afl->clean_trace_custom, afl->fsrv.trace_bits,
563*08b48e0bSAndroid Build Coastguard Worker                afl->fsrv.map_size);
564*08b48e0bSAndroid Build Coastguard Worker 
565*08b48e0bSAndroid Build Coastguard Worker       }
566*08b48e0bSAndroid Build Coastguard Worker 
567*08b48e0bSAndroid Build Coastguard Worker       if (afl_realloc((void **)&out_buf, retlen) == NULL) {
568*08b48e0bSAndroid Build Coastguard Worker 
569*08b48e0bSAndroid Build Coastguard Worker         FATAL("can not allocate memory for trim");
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker       }
572*08b48e0bSAndroid Build Coastguard Worker 
573*08b48e0bSAndroid Build Coastguard Worker       out_len = retlen;
574*08b48e0bSAndroid Build Coastguard Worker       // TODO are we sure that retbuf fits into out_buf if retbuf can actually
575*08b48e0bSAndroid Build Coastguard Worker       // increase in size?
576*08b48e0bSAndroid Build Coastguard Worker       memcpy(out_buf, retbuf, retlen);
577*08b48e0bSAndroid Build Coastguard Worker 
578*08b48e0bSAndroid Build Coastguard Worker       /* Tell the custom mutator that the trimming was successful */
579*08b48e0bSAndroid Build Coastguard Worker       afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 1);
580*08b48e0bSAndroid Build Coastguard Worker 
581*08b48e0bSAndroid Build Coastguard Worker       if (afl->not_on_tty && afl->debug) {
582*08b48e0bSAndroid Build Coastguard Worker 
583*08b48e0bSAndroid Build Coastguard Worker         SAYF("[Custom Trimming] SUCCESS: %u/%u iterations (now at %u bytes)",
584*08b48e0bSAndroid Build Coastguard Worker              afl->stage_cur, afl->stage_max, out_len);
585*08b48e0bSAndroid Build Coastguard Worker 
586*08b48e0bSAndroid Build Coastguard Worker       }
587*08b48e0bSAndroid Build Coastguard Worker 
588*08b48e0bSAndroid Build Coastguard Worker     } else {
589*08b48e0bSAndroid Build Coastguard Worker 
590*08b48e0bSAndroid Build Coastguard Worker       /* Tell the custom mutator that the trimming was unsuccessful */
591*08b48e0bSAndroid Build Coastguard Worker       s32 retval2 = mutator->afl_custom_post_trim(mutator->data, 0);
592*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(retval2 < 0)) {
593*08b48e0bSAndroid Build Coastguard Worker 
594*08b48e0bSAndroid Build Coastguard Worker         FATAL("Error ret in custom_post_trim: %d", retval2);
595*08b48e0bSAndroid Build Coastguard Worker 
596*08b48e0bSAndroid Build Coastguard Worker       } else {
597*08b48e0bSAndroid Build Coastguard Worker 
598*08b48e0bSAndroid Build Coastguard Worker         afl->stage_cur = retval2;
599*08b48e0bSAndroid Build Coastguard Worker 
600*08b48e0bSAndroid Build Coastguard Worker       }
601*08b48e0bSAndroid Build Coastguard Worker 
602*08b48e0bSAndroid Build Coastguard Worker       if (afl->not_on_tty && afl->debug) {
603*08b48e0bSAndroid Build Coastguard Worker 
604*08b48e0bSAndroid Build Coastguard Worker         SAYF("[Custom Trimming] FAILURE: %u/%u iterations", afl->stage_cur,
605*08b48e0bSAndroid Build Coastguard Worker              afl->stage_max);
606*08b48e0bSAndroid Build Coastguard Worker 
607*08b48e0bSAndroid Build Coastguard Worker       }
608*08b48e0bSAndroid Build Coastguard Worker 
609*08b48e0bSAndroid Build Coastguard Worker     }
610*08b48e0bSAndroid Build Coastguard Worker 
611*08b48e0bSAndroid Build Coastguard Worker     /* Since this can be slow, update the screen every now and then. */
612*08b48e0bSAndroid Build Coastguard Worker 
613*08b48e0bSAndroid Build Coastguard Worker     if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); }
614*08b48e0bSAndroid Build Coastguard Worker 
615*08b48e0bSAndroid Build Coastguard Worker   }
616*08b48e0bSAndroid Build Coastguard Worker 
617*08b48e0bSAndroid Build Coastguard Worker   /* If we have made changes, we also need to update the on-disk
618*08b48e0bSAndroid Build Coastguard Worker      version of the test case. */
619*08b48e0bSAndroid Build Coastguard Worker 
620*08b48e0bSAndroid Build Coastguard Worker   if (out_buf) {
621*08b48e0bSAndroid Build Coastguard Worker 
622*08b48e0bSAndroid Build Coastguard Worker     s32 fd;
623*08b48e0bSAndroid Build Coastguard Worker 
624*08b48e0bSAndroid Build Coastguard Worker     unlink(q->fname);                                      /* ignore errors */
625*08b48e0bSAndroid Build Coastguard Worker 
626*08b48e0bSAndroid Build Coastguard Worker     fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
627*08b48e0bSAndroid Build Coastguard Worker 
628*08b48e0bSAndroid Build Coastguard Worker     if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
629*08b48e0bSAndroid Build Coastguard Worker 
630*08b48e0bSAndroid Build Coastguard Worker     ck_write(fd, out_buf, out_len, q->fname);
631*08b48e0bSAndroid Build Coastguard Worker     close(fd);
632*08b48e0bSAndroid Build Coastguard Worker 
633*08b48e0bSAndroid Build Coastguard Worker     /* Update the queue's knowledge of length as soon as we write the file.
634*08b48e0bSAndroid Build Coastguard Worker        We do this here so that exit/error cases that *don't* update the file
635*08b48e0bSAndroid Build Coastguard Worker        also don't update q->len. */
636*08b48e0bSAndroid Build Coastguard Worker     q->len = out_len;
637*08b48e0bSAndroid Build Coastguard Worker 
638*08b48e0bSAndroid Build Coastguard Worker     memcpy(afl->fsrv.trace_bits, afl->clean_trace_custom, afl->fsrv.map_size);
639*08b48e0bSAndroid Build Coastguard Worker     update_bitmap_score(afl, q);
640*08b48e0bSAndroid Build Coastguard Worker 
641*08b48e0bSAndroid Build Coastguard Worker   }
642*08b48e0bSAndroid Build Coastguard Worker 
643*08b48e0bSAndroid Build Coastguard Worker   if (afl->not_on_tty && afl->debug) {
644*08b48e0bSAndroid Build Coastguard Worker 
645*08b48e0bSAndroid Build Coastguard Worker     SAYF("[Custom Trimming] DONE: %u bytes -> %u bytes", orig_len, q->len);
646*08b48e0bSAndroid Build Coastguard Worker 
647*08b48e0bSAndroid Build Coastguard Worker   }
648*08b48e0bSAndroid Build Coastguard Worker 
649*08b48e0bSAndroid Build Coastguard Worker abort_trimming:
650*08b48e0bSAndroid Build Coastguard Worker 
651*08b48e0bSAndroid Build Coastguard Worker   if (out_buf) afl_free(out_buf);
652*08b48e0bSAndroid Build Coastguard Worker   afl->bytes_trim_out += q->len;
653*08b48e0bSAndroid Build Coastguard Worker   return fault;
654*08b48e0bSAndroid Build Coastguard Worker 
655*08b48e0bSAndroid Build Coastguard Worker }
656*08b48e0bSAndroid Build Coastguard Worker 
657