xref: /aosp_15_r20/external/AFLplusplus/src/afl-fuzz-bitmap.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - bitmap related routines
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    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 
11*08b48e0bSAndroid Build Coastguard Worker    Copyright 2016, 2017 Google Inc. All rights reserved.
12*08b48e0bSAndroid Build Coastguard Worker    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
13*08b48e0bSAndroid Build Coastguard Worker 
14*08b48e0bSAndroid Build Coastguard Worker    Licensed under the Apache License, Version 2.0 (the "License");
15*08b48e0bSAndroid Build Coastguard Worker    you may not use this file except in compliance with the License.
16*08b48e0bSAndroid Build Coastguard Worker    You may obtain a copy of the License at:
17*08b48e0bSAndroid Build Coastguard Worker 
18*08b48e0bSAndroid Build Coastguard Worker      https://www.apache.org/licenses/LICENSE-2.0
19*08b48e0bSAndroid Build Coastguard Worker 
20*08b48e0bSAndroid Build Coastguard Worker    This is the real deal: the program takes an instrumented binary and
21*08b48e0bSAndroid Build Coastguard Worker    attempts a variety of basic fuzzing tricks, paying close attention to
22*08b48e0bSAndroid Build Coastguard Worker    how they affect the execution path.
23*08b48e0bSAndroid Build Coastguard Worker 
24*08b48e0bSAndroid Build Coastguard Worker  */
25*08b48e0bSAndroid Build Coastguard Worker 
26*08b48e0bSAndroid Build Coastguard Worker #include "afl-fuzz.h"
27*08b48e0bSAndroid Build Coastguard Worker #include <limits.h>
28*08b48e0bSAndroid Build Coastguard Worker #if !defined NAME_MAX
29*08b48e0bSAndroid Build Coastguard Worker   #define NAME_MAX _XOPEN_NAME_MAX
30*08b48e0bSAndroid Build Coastguard Worker #endif
31*08b48e0bSAndroid Build Coastguard Worker 
32*08b48e0bSAndroid Build Coastguard Worker /* Write bitmap to file. The bitmap is useful mostly for the secret
33*08b48e0bSAndroid Build Coastguard Worker    -B option, to focus a separate fuzzing session on a particular
34*08b48e0bSAndroid Build Coastguard Worker    interesting input without rediscovering all the others. */
35*08b48e0bSAndroid Build Coastguard Worker 
write_bitmap(afl_state_t * afl)36*08b48e0bSAndroid Build Coastguard Worker void write_bitmap(afl_state_t *afl) {
37*08b48e0bSAndroid Build Coastguard Worker 
38*08b48e0bSAndroid Build Coastguard Worker   u8  fname[PATH_MAX];
39*08b48e0bSAndroid Build Coastguard Worker   s32 fd;
40*08b48e0bSAndroid Build Coastguard Worker 
41*08b48e0bSAndroid Build Coastguard Worker   if (!afl->bitmap_changed) { return; }
42*08b48e0bSAndroid Build Coastguard Worker   afl->bitmap_changed = 0;
43*08b48e0bSAndroid Build Coastguard Worker 
44*08b48e0bSAndroid Build Coastguard Worker   snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
45*08b48e0bSAndroid Build Coastguard Worker   fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
46*08b48e0bSAndroid Build Coastguard Worker 
47*08b48e0bSAndroid Build Coastguard Worker   if (fd < 0) { PFATAL("Unable to open '%s'", fname); }
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker   ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname);
50*08b48e0bSAndroid Build Coastguard Worker 
51*08b48e0bSAndroid Build Coastguard Worker   close(fd);
52*08b48e0bSAndroid Build Coastguard Worker 
53*08b48e0bSAndroid Build Coastguard Worker }
54*08b48e0bSAndroid Build Coastguard Worker 
55*08b48e0bSAndroid Build Coastguard Worker /* Count the number of bits set in the provided bitmap. Used for the status
56*08b48e0bSAndroid Build Coastguard Worker    screen several times every second, does not have to be fast. */
57*08b48e0bSAndroid Build Coastguard Worker 
count_bits(afl_state_t * afl,u8 * mem)58*08b48e0bSAndroid Build Coastguard Worker u32 count_bits(afl_state_t *afl, u8 *mem) {
59*08b48e0bSAndroid Build Coastguard Worker 
60*08b48e0bSAndroid Build Coastguard Worker   u32 *ptr = (u32 *)mem;
61*08b48e0bSAndroid Build Coastguard Worker   u32  i = ((afl->fsrv.real_map_size + 3) >> 2);
62*08b48e0bSAndroid Build Coastguard Worker   u32  ret = 0;
63*08b48e0bSAndroid Build Coastguard Worker 
64*08b48e0bSAndroid Build Coastguard Worker   while (i--) {
65*08b48e0bSAndroid Build Coastguard Worker 
66*08b48e0bSAndroid Build Coastguard Worker     u32 v = *(ptr++);
67*08b48e0bSAndroid Build Coastguard Worker 
68*08b48e0bSAndroid Build Coastguard Worker     /* This gets called on the inverse, virgin bitmap; optimize for sparse
69*08b48e0bSAndroid Build Coastguard Worker        data. */
70*08b48e0bSAndroid Build Coastguard Worker 
71*08b48e0bSAndroid Build Coastguard Worker     if (likely(v == 0xffffffff)) {
72*08b48e0bSAndroid Build Coastguard Worker 
73*08b48e0bSAndroid Build Coastguard Worker       ret += 32;
74*08b48e0bSAndroid Build Coastguard Worker       continue;
75*08b48e0bSAndroid Build Coastguard Worker 
76*08b48e0bSAndroid Build Coastguard Worker     }
77*08b48e0bSAndroid Build Coastguard Worker 
78*08b48e0bSAndroid Build Coastguard Worker     v -= ((v >> 1) & 0x55555555);
79*08b48e0bSAndroid Build Coastguard Worker     v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
80*08b48e0bSAndroid Build Coastguard Worker     ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24;
81*08b48e0bSAndroid Build Coastguard Worker 
82*08b48e0bSAndroid Build Coastguard Worker   }
83*08b48e0bSAndroid Build Coastguard Worker 
84*08b48e0bSAndroid Build Coastguard Worker   return ret;
85*08b48e0bSAndroid Build Coastguard Worker 
86*08b48e0bSAndroid Build Coastguard Worker }
87*08b48e0bSAndroid Build Coastguard Worker 
88*08b48e0bSAndroid Build Coastguard Worker /* Count the number of bytes set in the bitmap. Called fairly sporadically,
89*08b48e0bSAndroid Build Coastguard Worker    mostly to update the status screen or calibrate and examine confirmed
90*08b48e0bSAndroid Build Coastguard Worker    new paths. */
91*08b48e0bSAndroid Build Coastguard Worker 
count_bytes(afl_state_t * afl,u8 * mem)92*08b48e0bSAndroid Build Coastguard Worker u32 count_bytes(afl_state_t *afl, u8 *mem) {
93*08b48e0bSAndroid Build Coastguard Worker 
94*08b48e0bSAndroid Build Coastguard Worker   u32 *ptr = (u32 *)mem;
95*08b48e0bSAndroid Build Coastguard Worker   u32  i = ((afl->fsrv.real_map_size + 3) >> 2);
96*08b48e0bSAndroid Build Coastguard Worker   u32  ret = 0;
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker   while (i--) {
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker     u32 v = *(ptr++);
101*08b48e0bSAndroid Build Coastguard Worker 
102*08b48e0bSAndroid Build Coastguard Worker     if (likely(!v)) { continue; }
103*08b48e0bSAndroid Build Coastguard Worker     if (v & 0x000000ffU) { ++ret; }
104*08b48e0bSAndroid Build Coastguard Worker     if (v & 0x0000ff00U) { ++ret; }
105*08b48e0bSAndroid Build Coastguard Worker     if (v & 0x00ff0000U) { ++ret; }
106*08b48e0bSAndroid Build Coastguard Worker     if (v & 0xff000000U) { ++ret; }
107*08b48e0bSAndroid Build Coastguard Worker 
108*08b48e0bSAndroid Build Coastguard Worker   }
109*08b48e0bSAndroid Build Coastguard Worker 
110*08b48e0bSAndroid Build Coastguard Worker   return ret;
111*08b48e0bSAndroid Build Coastguard Worker 
112*08b48e0bSAndroid Build Coastguard Worker }
113*08b48e0bSAndroid Build Coastguard Worker 
114*08b48e0bSAndroid Build Coastguard Worker /* Count the number of non-255 bytes set in the bitmap. Used strictly for the
115*08b48e0bSAndroid Build Coastguard Worker    status screen, several calls per second or so. */
116*08b48e0bSAndroid Build Coastguard Worker 
count_non_255_bytes(afl_state_t * afl,u8 * mem)117*08b48e0bSAndroid Build Coastguard Worker u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) {
118*08b48e0bSAndroid Build Coastguard Worker 
119*08b48e0bSAndroid Build Coastguard Worker   u32 *ptr = (u32 *)mem;
120*08b48e0bSAndroid Build Coastguard Worker   u32  i = ((afl->fsrv.real_map_size + 3) >> 2);
121*08b48e0bSAndroid Build Coastguard Worker   u32  ret = 0;
122*08b48e0bSAndroid Build Coastguard Worker 
123*08b48e0bSAndroid Build Coastguard Worker   while (i--) {
124*08b48e0bSAndroid Build Coastguard Worker 
125*08b48e0bSAndroid Build Coastguard Worker     u32 v = *(ptr++);
126*08b48e0bSAndroid Build Coastguard Worker 
127*08b48e0bSAndroid Build Coastguard Worker     /* This is called on the virgin bitmap, so optimize for the most likely
128*08b48e0bSAndroid Build Coastguard Worker        case. */
129*08b48e0bSAndroid Build Coastguard Worker 
130*08b48e0bSAndroid Build Coastguard Worker     if (likely(v == 0xffffffffU)) { continue; }
131*08b48e0bSAndroid Build Coastguard Worker     if ((v & 0x000000ffU) != 0x000000ffU) { ++ret; }
132*08b48e0bSAndroid Build Coastguard Worker     if ((v & 0x0000ff00U) != 0x0000ff00U) { ++ret; }
133*08b48e0bSAndroid Build Coastguard Worker     if ((v & 0x00ff0000U) != 0x00ff0000U) { ++ret; }
134*08b48e0bSAndroid Build Coastguard Worker     if ((v & 0xff000000U) != 0xff000000U) { ++ret; }
135*08b48e0bSAndroid Build Coastguard Worker 
136*08b48e0bSAndroid Build Coastguard Worker   }
137*08b48e0bSAndroid Build Coastguard Worker 
138*08b48e0bSAndroid Build Coastguard Worker   return ret;
139*08b48e0bSAndroid Build Coastguard Worker 
140*08b48e0bSAndroid Build Coastguard Worker }
141*08b48e0bSAndroid Build Coastguard Worker 
142*08b48e0bSAndroid Build Coastguard Worker /* Destructively simplify trace by eliminating hit count information
143*08b48e0bSAndroid Build Coastguard Worker    and replacing it with 0x80 or 0x01 depending on whether the tuple
144*08b48e0bSAndroid Build Coastguard Worker    is hit or not. Called on every new crash or timeout, should be
145*08b48e0bSAndroid Build Coastguard Worker    reasonably fast. */
146*08b48e0bSAndroid Build Coastguard Worker const u8 simplify_lookup[256] = {
147*08b48e0bSAndroid Build Coastguard Worker 
148*08b48e0bSAndroid Build Coastguard Worker     [0] = 1, [1 ... 255] = 128
149*08b48e0bSAndroid Build Coastguard Worker 
150*08b48e0bSAndroid Build Coastguard Worker };
151*08b48e0bSAndroid Build Coastguard Worker 
152*08b48e0bSAndroid Build Coastguard Worker /* Destructively classify execution counts in a trace. This is used as a
153*08b48e0bSAndroid Build Coastguard Worker    preprocessing step for any newly acquired traces. Called on every exec,
154*08b48e0bSAndroid Build Coastguard Worker    must be fast. */
155*08b48e0bSAndroid Build Coastguard Worker 
156*08b48e0bSAndroid Build Coastguard Worker const u8 count_class_lookup8[256] = {
157*08b48e0bSAndroid Build Coastguard Worker 
158*08b48e0bSAndroid Build Coastguard Worker     [0] = 0,
159*08b48e0bSAndroid Build Coastguard Worker     [1] = 1,
160*08b48e0bSAndroid Build Coastguard Worker     [2] = 2,
161*08b48e0bSAndroid Build Coastguard Worker     [3] = 4,
162*08b48e0bSAndroid Build Coastguard Worker     [4 ... 7] = 8,
163*08b48e0bSAndroid Build Coastguard Worker     [8 ... 15] = 16,
164*08b48e0bSAndroid Build Coastguard Worker     [16 ... 31] = 32,
165*08b48e0bSAndroid Build Coastguard Worker     [32 ... 127] = 64,
166*08b48e0bSAndroid Build Coastguard Worker     [128 ... 255] = 128
167*08b48e0bSAndroid Build Coastguard Worker 
168*08b48e0bSAndroid Build Coastguard Worker };
169*08b48e0bSAndroid Build Coastguard Worker 
170*08b48e0bSAndroid Build Coastguard Worker u16 count_class_lookup16[65536];
171*08b48e0bSAndroid Build Coastguard Worker 
init_count_class16(void)172*08b48e0bSAndroid Build Coastguard Worker void init_count_class16(void) {
173*08b48e0bSAndroid Build Coastguard Worker 
174*08b48e0bSAndroid Build Coastguard Worker   u32 b1, b2;
175*08b48e0bSAndroid Build Coastguard Worker 
176*08b48e0bSAndroid Build Coastguard Worker   for (b1 = 0; b1 < 256; b1++) {
177*08b48e0bSAndroid Build Coastguard Worker 
178*08b48e0bSAndroid Build Coastguard Worker     for (b2 = 0; b2 < 256; b2++) {
179*08b48e0bSAndroid Build Coastguard Worker 
180*08b48e0bSAndroid Build Coastguard Worker       count_class_lookup16[(b1 << 8) + b2] =
181*08b48e0bSAndroid Build Coastguard Worker           (count_class_lookup8[b1] << 8) | count_class_lookup8[b2];
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker     }
184*08b48e0bSAndroid Build Coastguard Worker 
185*08b48e0bSAndroid Build Coastguard Worker   }
186*08b48e0bSAndroid Build Coastguard Worker 
187*08b48e0bSAndroid Build Coastguard Worker }
188*08b48e0bSAndroid Build Coastguard Worker 
189*08b48e0bSAndroid Build Coastguard Worker /* Import coverage processing routines. */
190*08b48e0bSAndroid Build Coastguard Worker 
191*08b48e0bSAndroid Build Coastguard Worker #ifdef WORD_SIZE_64
192*08b48e0bSAndroid Build Coastguard Worker   #include "coverage-64.h"
193*08b48e0bSAndroid Build Coastguard Worker #else
194*08b48e0bSAndroid Build Coastguard Worker   #include "coverage-32.h"
195*08b48e0bSAndroid Build Coastguard Worker #endif
196*08b48e0bSAndroid Build Coastguard Worker 
197*08b48e0bSAndroid Build Coastguard Worker /* Check if the current execution path brings anything new to the table.
198*08b48e0bSAndroid Build Coastguard Worker    Update virgin bits to reflect the finds. Returns 1 if the only change is
199*08b48e0bSAndroid Build Coastguard Worker    the hit-count for a particular tuple; 2 if there are new tuples seen.
200*08b48e0bSAndroid Build Coastguard Worker    Updates the map, so subsequent calls will always return 0.
201*08b48e0bSAndroid Build Coastguard Worker 
202*08b48e0bSAndroid Build Coastguard Worker    This function is called after every exec() on a fairly large buffer, so
203*08b48e0bSAndroid Build Coastguard Worker    it needs to be fast. We do this in 32-bit and 64-bit flavors. */
204*08b48e0bSAndroid Build Coastguard Worker 
has_new_bits(afl_state_t * afl,u8 * virgin_map)205*08b48e0bSAndroid Build Coastguard Worker inline u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
206*08b48e0bSAndroid Build Coastguard Worker 
207*08b48e0bSAndroid Build Coastguard Worker #ifdef WORD_SIZE_64
208*08b48e0bSAndroid Build Coastguard Worker 
209*08b48e0bSAndroid Build Coastguard Worker   u64 *current = (u64 *)afl->fsrv.trace_bits;
210*08b48e0bSAndroid Build Coastguard Worker   u64 *virgin = (u64 *)virgin_map;
211*08b48e0bSAndroid Build Coastguard Worker 
212*08b48e0bSAndroid Build Coastguard Worker   u32 i = ((afl->fsrv.real_map_size + 7) >> 3);
213*08b48e0bSAndroid Build Coastguard Worker 
214*08b48e0bSAndroid Build Coastguard Worker #else
215*08b48e0bSAndroid Build Coastguard Worker 
216*08b48e0bSAndroid Build Coastguard Worker   u32 *current = (u32 *)afl->fsrv.trace_bits;
217*08b48e0bSAndroid Build Coastguard Worker   u32 *virgin = (u32 *)virgin_map;
218*08b48e0bSAndroid Build Coastguard Worker 
219*08b48e0bSAndroid Build Coastguard Worker   u32 i = ((afl->fsrv.real_map_size + 3) >> 2);
220*08b48e0bSAndroid Build Coastguard Worker 
221*08b48e0bSAndroid Build Coastguard Worker #endif                                                     /* ^WORD_SIZE_64 */
222*08b48e0bSAndroid Build Coastguard Worker 
223*08b48e0bSAndroid Build Coastguard Worker   u8 ret = 0;
224*08b48e0bSAndroid Build Coastguard Worker   while (i--) {
225*08b48e0bSAndroid Build Coastguard Worker 
226*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(*current)) discover_word(&ret, current, virgin);
227*08b48e0bSAndroid Build Coastguard Worker 
228*08b48e0bSAndroid Build Coastguard Worker     current++;
229*08b48e0bSAndroid Build Coastguard Worker     virgin++;
230*08b48e0bSAndroid Build Coastguard Worker 
231*08b48e0bSAndroid Build Coastguard Worker   }
232*08b48e0bSAndroid Build Coastguard Worker 
233*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(ret) && likely(virgin_map == afl->virgin_bits))
234*08b48e0bSAndroid Build Coastguard Worker     afl->bitmap_changed = 1;
235*08b48e0bSAndroid Build Coastguard Worker 
236*08b48e0bSAndroid Build Coastguard Worker   return ret;
237*08b48e0bSAndroid Build Coastguard Worker 
238*08b48e0bSAndroid Build Coastguard Worker }
239*08b48e0bSAndroid Build Coastguard Worker 
240*08b48e0bSAndroid Build Coastguard Worker /* A combination of classify_counts and has_new_bits. If 0 is returned, then the
241*08b48e0bSAndroid Build Coastguard Worker  * trace bits are kept as-is. Otherwise, the trace bits are overwritten with
242*08b48e0bSAndroid Build Coastguard Worker  * classified values.
243*08b48e0bSAndroid Build Coastguard Worker  *
244*08b48e0bSAndroid Build Coastguard Worker  * This accelerates the processing: in most cases, no interesting behavior
245*08b48e0bSAndroid Build Coastguard Worker  * happen, and the trace bits will be discarded soon. This function optimizes
246*08b48e0bSAndroid Build Coastguard Worker  * for such cases: one-pass scan on trace bits without modifying anything. Only
247*08b48e0bSAndroid Build Coastguard Worker  * on rare cases it fall backs to the slow path: classify_counts() first, then
248*08b48e0bSAndroid Build Coastguard Worker  * return has_new_bits(). */
249*08b48e0bSAndroid Build Coastguard Worker 
has_new_bits_unclassified(afl_state_t * afl,u8 * virgin_map)250*08b48e0bSAndroid Build Coastguard Worker inline u8 has_new_bits_unclassified(afl_state_t *afl, u8 *virgin_map) {
251*08b48e0bSAndroid Build Coastguard Worker 
252*08b48e0bSAndroid Build Coastguard Worker   /* Handle the hot path first: no new coverage */
253*08b48e0bSAndroid Build Coastguard Worker   u8 *end = afl->fsrv.trace_bits + afl->fsrv.map_size;
254*08b48e0bSAndroid Build Coastguard Worker 
255*08b48e0bSAndroid Build Coastguard Worker #ifdef WORD_SIZE_64
256*08b48e0bSAndroid Build Coastguard Worker 
257*08b48e0bSAndroid Build Coastguard Worker   if (!skim((u64 *)virgin_map, (u64 *)afl->fsrv.trace_bits, (u64 *)end))
258*08b48e0bSAndroid Build Coastguard Worker     return 0;
259*08b48e0bSAndroid Build Coastguard Worker 
260*08b48e0bSAndroid Build Coastguard Worker #else
261*08b48e0bSAndroid Build Coastguard Worker 
262*08b48e0bSAndroid Build Coastguard Worker   if (!skim((u32 *)virgin_map, (u32 *)afl->fsrv.trace_bits, (u32 *)end))
263*08b48e0bSAndroid Build Coastguard Worker     return 0;
264*08b48e0bSAndroid Build Coastguard Worker 
265*08b48e0bSAndroid Build Coastguard Worker #endif                                                     /* ^WORD_SIZE_64 */
266*08b48e0bSAndroid Build Coastguard Worker   classify_counts(&afl->fsrv);
267*08b48e0bSAndroid Build Coastguard Worker   return has_new_bits(afl, virgin_map);
268*08b48e0bSAndroid Build Coastguard Worker 
269*08b48e0bSAndroid Build Coastguard Worker }
270*08b48e0bSAndroid Build Coastguard Worker 
271*08b48e0bSAndroid Build Coastguard Worker /* Compact trace bytes into a smaller bitmap. We effectively just drop the
272*08b48e0bSAndroid Build Coastguard Worker    count information here. This is called only sporadically, for some
273*08b48e0bSAndroid Build Coastguard Worker    new paths. */
274*08b48e0bSAndroid Build Coastguard Worker 
minimize_bits(afl_state_t * afl,u8 * dst,u8 * src)275*08b48e0bSAndroid Build Coastguard Worker void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) {
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker   u32 i = 0;
278*08b48e0bSAndroid Build Coastguard Worker 
279*08b48e0bSAndroid Build Coastguard Worker   while (i < afl->fsrv.map_size) {
280*08b48e0bSAndroid Build Coastguard Worker 
281*08b48e0bSAndroid Build Coastguard Worker     if (*(src++)) { dst[i >> 3] |= 1 << (i & 7); }
282*08b48e0bSAndroid Build Coastguard Worker     ++i;
283*08b48e0bSAndroid Build Coastguard Worker 
284*08b48e0bSAndroid Build Coastguard Worker   }
285*08b48e0bSAndroid Build Coastguard Worker 
286*08b48e0bSAndroid Build Coastguard Worker }
287*08b48e0bSAndroid Build Coastguard Worker 
288*08b48e0bSAndroid Build Coastguard Worker #ifndef SIMPLE_FILES
289*08b48e0bSAndroid Build Coastguard Worker 
290*08b48e0bSAndroid Build Coastguard Worker /* Construct a file name for a new test case, capturing the operation
291*08b48e0bSAndroid Build Coastguard Worker    that led to its discovery. Returns a ptr to afl->describe_op_buf_256. */
292*08b48e0bSAndroid Build Coastguard Worker 
describe_op(afl_state_t * afl,u8 new_bits,size_t max_description_len)293*08b48e0bSAndroid Build Coastguard Worker u8 *describe_op(afl_state_t *afl, u8 new_bits, size_t max_description_len) {
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker   u8 is_timeout = 0;
296*08b48e0bSAndroid Build Coastguard Worker 
297*08b48e0bSAndroid Build Coastguard Worker   if (new_bits & 0xf0) {
298*08b48e0bSAndroid Build Coastguard Worker 
299*08b48e0bSAndroid Build Coastguard Worker     new_bits -= 0x80;
300*08b48e0bSAndroid Build Coastguard Worker     is_timeout = 1;
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker   }
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker   size_t real_max_len =
305*08b48e0bSAndroid Build Coastguard Worker       MIN(max_description_len, sizeof(afl->describe_op_buf_256));
306*08b48e0bSAndroid Build Coastguard Worker   u8 *ret = afl->describe_op_buf_256;
307*08b48e0bSAndroid Build Coastguard Worker 
308*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(afl->syncing_party)) {
309*08b48e0bSAndroid Build Coastguard Worker 
310*08b48e0bSAndroid Build Coastguard Worker     sprintf(ret, "sync:%s,src:%06u", afl->syncing_party, afl->syncing_case);
311*08b48e0bSAndroid Build Coastguard Worker 
312*08b48e0bSAndroid Build Coastguard Worker   } else {
313*08b48e0bSAndroid Build Coastguard Worker 
314*08b48e0bSAndroid Build Coastguard Worker     sprintf(ret, "src:%06u", afl->current_entry);
315*08b48e0bSAndroid Build Coastguard Worker 
316*08b48e0bSAndroid Build Coastguard Worker     if (afl->splicing_with >= 0) {
317*08b48e0bSAndroid Build Coastguard Worker 
318*08b48e0bSAndroid Build Coastguard Worker       sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
319*08b48e0bSAndroid Build Coastguard Worker 
320*08b48e0bSAndroid Build Coastguard Worker     }
321*08b48e0bSAndroid Build Coastguard Worker 
322*08b48e0bSAndroid Build Coastguard Worker     sprintf(ret + strlen(ret), ",time:%llu,execs:%llu",
323*08b48e0bSAndroid Build Coastguard Worker             get_cur_time() + afl->prev_run_time - afl->start_time,
324*08b48e0bSAndroid Build Coastguard Worker             afl->fsrv.total_execs);
325*08b48e0bSAndroid Build Coastguard Worker 
326*08b48e0bSAndroid Build Coastguard Worker     if (afl->current_custom_fuzz &&
327*08b48e0bSAndroid Build Coastguard Worker         afl->current_custom_fuzz->afl_custom_describe) {
328*08b48e0bSAndroid Build Coastguard Worker 
329*08b48e0bSAndroid Build Coastguard Worker       /* We are currently in a custom mutator that supports afl_custom_describe,
330*08b48e0bSAndroid Build Coastguard Worker        * use it! */
331*08b48e0bSAndroid Build Coastguard Worker 
332*08b48e0bSAndroid Build Coastguard Worker       size_t len_current = strlen(ret);
333*08b48e0bSAndroid Build Coastguard Worker       ret[len_current++] = ',';
334*08b48e0bSAndroid Build Coastguard Worker       ret[len_current] = '\0';
335*08b48e0bSAndroid Build Coastguard Worker 
336*08b48e0bSAndroid Build Coastguard Worker       ssize_t size_left = real_max_len - len_current - strlen(",+cov") - 2;
337*08b48e0bSAndroid Build Coastguard Worker       if (is_timeout) { size_left -= strlen(",+tout"); }
338*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(size_left <= 0)) FATAL("filename got too long");
339*08b48e0bSAndroid Build Coastguard Worker 
340*08b48e0bSAndroid Build Coastguard Worker       const char *custom_description =
341*08b48e0bSAndroid Build Coastguard Worker           afl->current_custom_fuzz->afl_custom_describe(
342*08b48e0bSAndroid Build Coastguard Worker               afl->current_custom_fuzz->data, size_left);
343*08b48e0bSAndroid Build Coastguard Worker       if (!custom_description || !custom_description[0]) {
344*08b48e0bSAndroid Build Coastguard Worker 
345*08b48e0bSAndroid Build Coastguard Worker         DEBUGF("Error getting a description from afl_custom_describe");
346*08b48e0bSAndroid Build Coastguard Worker         /* Take the stage name as description fallback */
347*08b48e0bSAndroid Build Coastguard Worker         sprintf(ret + len_current, "op:%s", afl->stage_short);
348*08b48e0bSAndroid Build Coastguard Worker 
349*08b48e0bSAndroid Build Coastguard Worker       } else {
350*08b48e0bSAndroid Build Coastguard Worker 
351*08b48e0bSAndroid Build Coastguard Worker         /* We got a proper custom description, use it */
352*08b48e0bSAndroid Build Coastguard Worker         strncat(ret + len_current, custom_description, size_left);
353*08b48e0bSAndroid Build Coastguard Worker 
354*08b48e0bSAndroid Build Coastguard Worker       }
355*08b48e0bSAndroid Build Coastguard Worker 
356*08b48e0bSAndroid Build Coastguard Worker     } else {
357*08b48e0bSAndroid Build Coastguard Worker 
358*08b48e0bSAndroid Build Coastguard Worker       /* Normal testcase descriptions start here */
359*08b48e0bSAndroid Build Coastguard Worker       sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
360*08b48e0bSAndroid Build Coastguard Worker 
361*08b48e0bSAndroid Build Coastguard Worker       if (afl->stage_cur_byte >= 0) {
362*08b48e0bSAndroid Build Coastguard Worker 
363*08b48e0bSAndroid Build Coastguard Worker         sprintf(ret + strlen(ret), ",pos:%d", afl->stage_cur_byte);
364*08b48e0bSAndroid Build Coastguard Worker 
365*08b48e0bSAndroid Build Coastguard Worker         if (afl->stage_val_type != STAGE_VAL_NONE) {
366*08b48e0bSAndroid Build Coastguard Worker 
367*08b48e0bSAndroid Build Coastguard Worker           sprintf(ret + strlen(ret), ",val:%s%+d",
368*08b48e0bSAndroid Build Coastguard Worker                   (afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "",
369*08b48e0bSAndroid Build Coastguard Worker                   afl->stage_cur_val);
370*08b48e0bSAndroid Build Coastguard Worker 
371*08b48e0bSAndroid Build Coastguard Worker         }
372*08b48e0bSAndroid Build Coastguard Worker 
373*08b48e0bSAndroid Build Coastguard Worker       } else {
374*08b48e0bSAndroid Build Coastguard Worker 
375*08b48e0bSAndroid Build Coastguard Worker         sprintf(ret + strlen(ret), ",rep:%d", afl->stage_cur_val);
376*08b48e0bSAndroid Build Coastguard Worker 
377*08b48e0bSAndroid Build Coastguard Worker       }
378*08b48e0bSAndroid Build Coastguard Worker 
379*08b48e0bSAndroid Build Coastguard Worker     }
380*08b48e0bSAndroid Build Coastguard Worker 
381*08b48e0bSAndroid Build Coastguard Worker   }
382*08b48e0bSAndroid Build Coastguard Worker 
383*08b48e0bSAndroid Build Coastguard Worker   if (is_timeout) { strcat(ret, ",+tout"); }
384*08b48e0bSAndroid Build Coastguard Worker 
385*08b48e0bSAndroid Build Coastguard Worker   if (new_bits == 2) { strcat(ret, ",+cov"); }
386*08b48e0bSAndroid Build Coastguard Worker 
387*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(strlen(ret) >= max_description_len))
388*08b48e0bSAndroid Build Coastguard Worker     FATAL("describe string is too long");
389*08b48e0bSAndroid Build Coastguard Worker 
390*08b48e0bSAndroid Build Coastguard Worker   return ret;
391*08b48e0bSAndroid Build Coastguard Worker 
392*08b48e0bSAndroid Build Coastguard Worker }
393*08b48e0bSAndroid Build Coastguard Worker 
394*08b48e0bSAndroid Build Coastguard Worker #endif                                                     /* !SIMPLE_FILES */
395*08b48e0bSAndroid Build Coastguard Worker 
396*08b48e0bSAndroid Build Coastguard Worker /* Write a message accompanying the crash directory :-) */
397*08b48e0bSAndroid Build Coastguard Worker 
write_crash_readme(afl_state_t * afl)398*08b48e0bSAndroid Build Coastguard Worker void write_crash_readme(afl_state_t *afl) {
399*08b48e0bSAndroid Build Coastguard Worker 
400*08b48e0bSAndroid Build Coastguard Worker   u8    fn[PATH_MAX];
401*08b48e0bSAndroid Build Coastguard Worker   s32   fd;
402*08b48e0bSAndroid Build Coastguard Worker   FILE *f;
403*08b48e0bSAndroid Build Coastguard Worker 
404*08b48e0bSAndroid Build Coastguard Worker   u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
405*08b48e0bSAndroid Build Coastguard Worker 
406*08b48e0bSAndroid Build Coastguard Worker   sprintf(fn, "%s/crashes/README.txt", afl->out_dir);
407*08b48e0bSAndroid Build Coastguard Worker 
408*08b48e0bSAndroid Build Coastguard Worker   fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
409*08b48e0bSAndroid Build Coastguard Worker 
410*08b48e0bSAndroid Build Coastguard Worker   /* Do not die on errors here - that would be impolite. */
411*08b48e0bSAndroid Build Coastguard Worker 
412*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(fd < 0)) { return; }
413*08b48e0bSAndroid Build Coastguard Worker 
414*08b48e0bSAndroid Build Coastguard Worker   f = fdopen(fd, "w");
415*08b48e0bSAndroid Build Coastguard Worker 
416*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(!f)) {
417*08b48e0bSAndroid Build Coastguard Worker 
418*08b48e0bSAndroid Build Coastguard Worker     close(fd);
419*08b48e0bSAndroid Build Coastguard Worker     return;
420*08b48e0bSAndroid Build Coastguard Worker 
421*08b48e0bSAndroid Build Coastguard Worker   }
422*08b48e0bSAndroid Build Coastguard Worker 
423*08b48e0bSAndroid Build Coastguard Worker   fprintf(
424*08b48e0bSAndroid Build Coastguard Worker       f,
425*08b48e0bSAndroid Build Coastguard Worker       "Command line used to find this crash:\n\n"
426*08b48e0bSAndroid Build Coastguard Worker 
427*08b48e0bSAndroid Build Coastguard Worker       "%s\n\n"
428*08b48e0bSAndroid Build Coastguard Worker 
429*08b48e0bSAndroid Build Coastguard Worker       "If you can't reproduce a bug outside of afl-fuzz, be sure to set the "
430*08b48e0bSAndroid Build Coastguard Worker       "same\n"
431*08b48e0bSAndroid Build Coastguard Worker       "memory limit. The limit used for this fuzzing session was %s.\n\n"
432*08b48e0bSAndroid Build Coastguard Worker 
433*08b48e0bSAndroid Build Coastguard Worker       "Need a tool to minimize test cases before investigating the crashes or "
434*08b48e0bSAndroid Build Coastguard Worker       "sending\n"
435*08b48e0bSAndroid Build Coastguard Worker       "them to a vendor? Check out the afl-tmin that comes with the fuzzer!\n\n"
436*08b48e0bSAndroid Build Coastguard Worker 
437*08b48e0bSAndroid Build Coastguard Worker       "Found any cool bugs in open-source tools using afl-fuzz? If yes, please "
438*08b48e0bSAndroid Build Coastguard Worker       "post\n"
439*08b48e0bSAndroid Build Coastguard Worker       "to https://github.com/AFLplusplus/AFLplusplus/issues/286 once the "
440*08b48e0bSAndroid Build Coastguard Worker       "issues\n"
441*08b48e0bSAndroid Build Coastguard Worker       " are fixed :)\n\n",
442*08b48e0bSAndroid Build Coastguard Worker 
443*08b48e0bSAndroid Build Coastguard Worker       afl->orig_cmdline,
444*08b48e0bSAndroid Build Coastguard Worker       stringify_mem_size(val_buf, sizeof(val_buf),
445*08b48e0bSAndroid Build Coastguard Worker                          afl->fsrv.mem_limit << 20));      /* ignore errors */
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker   fclose(f);
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker }
450*08b48e0bSAndroid Build Coastguard Worker 
451*08b48e0bSAndroid Build Coastguard Worker /* Check if the result of an execve() during routine fuzzing is interesting,
452*08b48e0bSAndroid Build Coastguard Worker    save or queue the input test case for further analysis if so. Returns 1 if
453*08b48e0bSAndroid Build Coastguard Worker    entry is saved, 0 otherwise. */
454*08b48e0bSAndroid Build Coastguard Worker 
455*08b48e0bSAndroid Build Coastguard Worker u8 __attribute__((hot))
save_if_interesting(afl_state_t * afl,void * mem,u32 len,u8 fault)456*08b48e0bSAndroid Build Coastguard Worker save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
457*08b48e0bSAndroid Build Coastguard Worker 
458*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(len == 0)) { return 0; }
459*08b48e0bSAndroid Build Coastguard Worker 
460*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) {
461*08b48e0bSAndroid Build Coastguard Worker 
462*08b48e0bSAndroid Build Coastguard Worker     if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
463*08b48e0bSAndroid Build Coastguard Worker 
464*08b48e0bSAndroid Build Coastguard Worker       classify_counts(&afl->fsrv);
465*08b48e0bSAndroid Build Coastguard Worker       u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
466*08b48e0bSAndroid Build Coastguard Worker 
467*08b48e0bSAndroid Build Coastguard Worker       // Saturated increment
468*08b48e0bSAndroid Build Coastguard Worker       if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
469*08b48e0bSAndroid Build Coastguard Worker         afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
470*08b48e0bSAndroid Build Coastguard Worker 
471*08b48e0bSAndroid Build Coastguard Worker     }
472*08b48e0bSAndroid Build Coastguard Worker 
473*08b48e0bSAndroid Build Coastguard Worker     return 0;
474*08b48e0bSAndroid Build Coastguard Worker 
475*08b48e0bSAndroid Build Coastguard Worker   }
476*08b48e0bSAndroid Build Coastguard Worker 
477*08b48e0bSAndroid Build Coastguard Worker   u8  fn[PATH_MAX];
478*08b48e0bSAndroid Build Coastguard Worker   u8 *queue_fn = "";
479*08b48e0bSAndroid Build Coastguard Worker   u8  new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0,
480*08b48e0bSAndroid Build Coastguard Worker      need_hash = 1;
481*08b48e0bSAndroid Build Coastguard Worker   s32 fd;
482*08b48e0bSAndroid Build Coastguard Worker   u64 cksum = 0;
483*08b48e0bSAndroid Build Coastguard Worker 
484*08b48e0bSAndroid Build Coastguard Worker   /* Update path frequency. */
485*08b48e0bSAndroid Build Coastguard Worker 
486*08b48e0bSAndroid Build Coastguard Worker   /* Generating a hash on every input is super expensive. Bad idea and should
487*08b48e0bSAndroid Build Coastguard Worker      only be used for special schedules */
488*08b48e0bSAndroid Build Coastguard Worker   if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
489*08b48e0bSAndroid Build Coastguard Worker 
490*08b48e0bSAndroid Build Coastguard Worker     classify_counts(&afl->fsrv);
491*08b48e0bSAndroid Build Coastguard Worker     classified = 1;
492*08b48e0bSAndroid Build Coastguard Worker     need_hash = 0;
493*08b48e0bSAndroid Build Coastguard Worker 
494*08b48e0bSAndroid Build Coastguard Worker     cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
495*08b48e0bSAndroid Build Coastguard Worker 
496*08b48e0bSAndroid Build Coastguard Worker     /* Saturated increment */
497*08b48e0bSAndroid Build Coastguard Worker     if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
498*08b48e0bSAndroid Build Coastguard Worker       afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
499*08b48e0bSAndroid Build Coastguard Worker 
500*08b48e0bSAndroid Build Coastguard Worker   }
501*08b48e0bSAndroid Build Coastguard Worker 
502*08b48e0bSAndroid Build Coastguard Worker   if (likely(fault == afl->crash_mode)) {
503*08b48e0bSAndroid Build Coastguard Worker 
504*08b48e0bSAndroid Build Coastguard Worker     /* Keep only if there are new bits in the map, add to queue for
505*08b48e0bSAndroid Build Coastguard Worker        future fuzzing, etc. */
506*08b48e0bSAndroid Build Coastguard Worker 
507*08b48e0bSAndroid Build Coastguard Worker     if (likely(classified)) {
508*08b48e0bSAndroid Build Coastguard Worker 
509*08b48e0bSAndroid Build Coastguard Worker       new_bits = has_new_bits(afl, afl->virgin_bits);
510*08b48e0bSAndroid Build Coastguard Worker 
511*08b48e0bSAndroid Build Coastguard Worker     } else {
512*08b48e0bSAndroid Build Coastguard Worker 
513*08b48e0bSAndroid Build Coastguard Worker       new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
514*08b48e0bSAndroid Build Coastguard Worker 
515*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(new_bits)) { classified = 1; }
516*08b48e0bSAndroid Build Coastguard Worker 
517*08b48e0bSAndroid Build Coastguard Worker     }
518*08b48e0bSAndroid Build Coastguard Worker 
519*08b48e0bSAndroid Build Coastguard Worker     if (likely(!new_bits)) {
520*08b48e0bSAndroid Build Coastguard Worker 
521*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(afl->crash_mode)) { ++afl->total_crashes; }
522*08b48e0bSAndroid Build Coastguard Worker       return 0;
523*08b48e0bSAndroid Build Coastguard Worker 
524*08b48e0bSAndroid Build Coastguard Worker     }
525*08b48e0bSAndroid Build Coastguard Worker 
526*08b48e0bSAndroid Build Coastguard Worker   save_to_queue:
527*08b48e0bSAndroid Build Coastguard Worker 
528*08b48e0bSAndroid Build Coastguard Worker #ifndef SIMPLE_FILES
529*08b48e0bSAndroid Build Coastguard Worker 
530*08b48e0bSAndroid Build Coastguard Worker     queue_fn =
531*08b48e0bSAndroid Build Coastguard Worker         alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_items,
532*08b48e0bSAndroid Build Coastguard Worker                      describe_op(afl, new_bits + is_timeout,
533*08b48e0bSAndroid Build Coastguard Worker                                  NAME_MAX - strlen("id:000000,")));
534*08b48e0bSAndroid Build Coastguard Worker 
535*08b48e0bSAndroid Build Coastguard Worker #else
536*08b48e0bSAndroid Build Coastguard Worker 
537*08b48e0bSAndroid Build Coastguard Worker     queue_fn =
538*08b48e0bSAndroid Build Coastguard Worker         alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_items);
539*08b48e0bSAndroid Build Coastguard Worker 
540*08b48e0bSAndroid Build Coastguard Worker #endif                                                    /* ^!SIMPLE_FILES */
541*08b48e0bSAndroid Build Coastguard Worker     fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
542*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); }
543*08b48e0bSAndroid Build Coastguard Worker     ck_write(fd, mem, len, queue_fn);
544*08b48e0bSAndroid Build Coastguard Worker     close(fd);
545*08b48e0bSAndroid Build Coastguard Worker     add_to_queue(afl, queue_fn, len, 0);
546*08b48e0bSAndroid Build Coastguard Worker 
547*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(afl->fuzz_mode) &&
548*08b48e0bSAndroid Build Coastguard Worker         likely(afl->switch_fuzz_mode && !afl->non_instrumented_mode)) {
549*08b48e0bSAndroid Build Coastguard Worker 
550*08b48e0bSAndroid Build Coastguard Worker       if (afl->afl_env.afl_no_ui) {
551*08b48e0bSAndroid Build Coastguard Worker 
552*08b48e0bSAndroid Build Coastguard Worker         ACTF("New coverage found, switching back to exploration mode.");
553*08b48e0bSAndroid Build Coastguard Worker 
554*08b48e0bSAndroid Build Coastguard Worker       }
555*08b48e0bSAndroid Build Coastguard Worker 
556*08b48e0bSAndroid Build Coastguard Worker       afl->fuzz_mode = 0;
557*08b48e0bSAndroid Build Coastguard Worker 
558*08b48e0bSAndroid Build Coastguard Worker     }
559*08b48e0bSAndroid Build Coastguard Worker 
560*08b48e0bSAndroid Build Coastguard Worker #ifdef INTROSPECTION
561*08b48e0bSAndroid Build Coastguard Worker     if (afl->custom_mutators_count && afl->current_custom_fuzz) {
562*08b48e0bSAndroid Build Coastguard Worker 
563*08b48e0bSAndroid Build Coastguard Worker       LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
564*08b48e0bSAndroid Build Coastguard Worker 
565*08b48e0bSAndroid Build Coastguard Worker         if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
566*08b48e0bSAndroid Build Coastguard Worker 
567*08b48e0bSAndroid Build Coastguard Worker           const char *ptr = el->afl_custom_introspection(el->data);
568*08b48e0bSAndroid Build Coastguard Worker 
569*08b48e0bSAndroid Build Coastguard Worker           if (ptr != NULL && *ptr != 0) {
570*08b48e0bSAndroid Build Coastguard Worker 
571*08b48e0bSAndroid Build Coastguard Worker             fprintf(afl->introspection_file, "QUEUE CUSTOM %s = %s\n", ptr,
572*08b48e0bSAndroid Build Coastguard Worker                     afl->queue_top->fname);
573*08b48e0bSAndroid Build Coastguard Worker 
574*08b48e0bSAndroid Build Coastguard Worker           }
575*08b48e0bSAndroid Build Coastguard Worker 
576*08b48e0bSAndroid Build Coastguard Worker         }
577*08b48e0bSAndroid Build Coastguard Worker 
578*08b48e0bSAndroid Build Coastguard Worker       });
579*08b48e0bSAndroid Build Coastguard Worker 
580*08b48e0bSAndroid Build Coastguard Worker     } else if (afl->mutation[0] != 0) {
581*08b48e0bSAndroid Build Coastguard Worker 
582*08b48e0bSAndroid Build Coastguard Worker       fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation,
583*08b48e0bSAndroid Build Coastguard Worker               afl->queue_top->fname);
584*08b48e0bSAndroid Build Coastguard Worker 
585*08b48e0bSAndroid Build Coastguard Worker     }
586*08b48e0bSAndroid Build Coastguard Worker 
587*08b48e0bSAndroid Build Coastguard Worker #endif
588*08b48e0bSAndroid Build Coastguard Worker 
589*08b48e0bSAndroid Build Coastguard Worker     if (new_bits == 2) {
590*08b48e0bSAndroid Build Coastguard Worker 
591*08b48e0bSAndroid Build Coastguard Worker       afl->queue_top->has_new_cov = 1;
592*08b48e0bSAndroid Build Coastguard Worker       ++afl->queued_with_cov;
593*08b48e0bSAndroid Build Coastguard Worker 
594*08b48e0bSAndroid Build Coastguard Worker     }
595*08b48e0bSAndroid Build Coastguard Worker 
596*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(need_hash && new_bits)) {
597*08b48e0bSAndroid Build Coastguard Worker 
598*08b48e0bSAndroid Build Coastguard Worker       /* due to classify counts we have to recalculate the checksum */
599*08b48e0bSAndroid Build Coastguard Worker       afl->queue_top->exec_cksum =
600*08b48e0bSAndroid Build Coastguard Worker           hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
601*08b48e0bSAndroid Build Coastguard Worker       need_hash = 0;
602*08b48e0bSAndroid Build Coastguard Worker 
603*08b48e0bSAndroid Build Coastguard Worker     }
604*08b48e0bSAndroid Build Coastguard Worker 
605*08b48e0bSAndroid Build Coastguard Worker     /* For AFLFast schedules we update the new queue entry */
606*08b48e0bSAndroid Build Coastguard Worker     if (likely(cksum)) {
607*08b48e0bSAndroid Build Coastguard Worker 
608*08b48e0bSAndroid Build Coastguard Worker       afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
609*08b48e0bSAndroid Build Coastguard Worker       afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
610*08b48e0bSAndroid Build Coastguard Worker 
611*08b48e0bSAndroid Build Coastguard Worker     }
612*08b48e0bSAndroid Build Coastguard Worker 
613*08b48e0bSAndroid Build Coastguard Worker     /* Try to calibrate inline; this also calls update_bitmap_score() when
614*08b48e0bSAndroid Build Coastguard Worker        successful. */
615*08b48e0bSAndroid Build Coastguard Worker     res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
616*08b48e0bSAndroid Build Coastguard Worker 
617*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(res == FSRV_RUN_ERROR)) {
618*08b48e0bSAndroid Build Coastguard Worker 
619*08b48e0bSAndroid Build Coastguard Worker       FATAL("Unable to execute target application");
620*08b48e0bSAndroid Build Coastguard Worker 
621*08b48e0bSAndroid Build Coastguard Worker     }
622*08b48e0bSAndroid Build Coastguard Worker 
623*08b48e0bSAndroid Build Coastguard Worker     if (likely(afl->q_testcase_max_cache_size)) {
624*08b48e0bSAndroid Build Coastguard Worker 
625*08b48e0bSAndroid Build Coastguard Worker       queue_testcase_store_mem(afl, afl->queue_top, mem);
626*08b48e0bSAndroid Build Coastguard Worker 
627*08b48e0bSAndroid Build Coastguard Worker     }
628*08b48e0bSAndroid Build Coastguard Worker 
629*08b48e0bSAndroid Build Coastguard Worker     keeping = 1;
630*08b48e0bSAndroid Build Coastguard Worker 
631*08b48e0bSAndroid Build Coastguard Worker   }
632*08b48e0bSAndroid Build Coastguard Worker 
633*08b48e0bSAndroid Build Coastguard Worker   switch (fault) {
634*08b48e0bSAndroid Build Coastguard Worker 
635*08b48e0bSAndroid Build Coastguard Worker     case FSRV_RUN_TMOUT:
636*08b48e0bSAndroid Build Coastguard Worker 
637*08b48e0bSAndroid Build Coastguard Worker       /* Timeouts are not very interesting, but we're still obliged to keep
638*08b48e0bSAndroid Build Coastguard Worker          a handful of samples. We use the presence of new bits in the
639*08b48e0bSAndroid Build Coastguard Worker          hang-specific bitmap as a signal of uniqueness. In "non-instrumented"
640*08b48e0bSAndroid Build Coastguard Worker          mode, we just keep everything. */
641*08b48e0bSAndroid Build Coastguard Worker 
642*08b48e0bSAndroid Build Coastguard Worker       ++afl->total_tmouts;
643*08b48e0bSAndroid Build Coastguard Worker 
644*08b48e0bSAndroid Build Coastguard Worker       if (afl->saved_hangs >= KEEP_UNIQUE_HANG) { return keeping; }
645*08b48e0bSAndroid Build Coastguard Worker 
646*08b48e0bSAndroid Build Coastguard Worker       if (likely(!afl->non_instrumented_mode)) {
647*08b48e0bSAndroid Build Coastguard Worker 
648*08b48e0bSAndroid Build Coastguard Worker         if (unlikely(!classified)) {
649*08b48e0bSAndroid Build Coastguard Worker 
650*08b48e0bSAndroid Build Coastguard Worker           classify_counts(&afl->fsrv);
651*08b48e0bSAndroid Build Coastguard Worker           classified = 1;
652*08b48e0bSAndroid Build Coastguard Worker 
653*08b48e0bSAndroid Build Coastguard Worker         }
654*08b48e0bSAndroid Build Coastguard Worker 
655*08b48e0bSAndroid Build Coastguard Worker         simplify_trace(afl, afl->fsrv.trace_bits);
656*08b48e0bSAndroid Build Coastguard Worker 
657*08b48e0bSAndroid Build Coastguard Worker         if (!has_new_bits(afl, afl->virgin_tmout)) { return keeping; }
658*08b48e0bSAndroid Build Coastguard Worker 
659*08b48e0bSAndroid Build Coastguard Worker       }
660*08b48e0bSAndroid Build Coastguard Worker 
661*08b48e0bSAndroid Build Coastguard Worker       is_timeout = 0x80;
662*08b48e0bSAndroid Build Coastguard Worker #ifdef INTROSPECTION
663*08b48e0bSAndroid Build Coastguard Worker       if (afl->custom_mutators_count && afl->current_custom_fuzz) {
664*08b48e0bSAndroid Build Coastguard Worker 
665*08b48e0bSAndroid Build Coastguard Worker         LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
666*08b48e0bSAndroid Build Coastguard Worker 
667*08b48e0bSAndroid Build Coastguard Worker           if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
668*08b48e0bSAndroid Build Coastguard Worker 
669*08b48e0bSAndroid Build Coastguard Worker             const char *ptr = el->afl_custom_introspection(el->data);
670*08b48e0bSAndroid Build Coastguard Worker 
671*08b48e0bSAndroid Build Coastguard Worker             if (ptr != NULL && *ptr != 0) {
672*08b48e0bSAndroid Build Coastguard Worker 
673*08b48e0bSAndroid Build Coastguard Worker               fprintf(afl->introspection_file,
674*08b48e0bSAndroid Build Coastguard Worker                       "UNIQUE_TIMEOUT CUSTOM %s = %s\n", ptr,
675*08b48e0bSAndroid Build Coastguard Worker                       afl->queue_top->fname);
676*08b48e0bSAndroid Build Coastguard Worker 
677*08b48e0bSAndroid Build Coastguard Worker             }
678*08b48e0bSAndroid Build Coastguard Worker 
679*08b48e0bSAndroid Build Coastguard Worker           }
680*08b48e0bSAndroid Build Coastguard Worker 
681*08b48e0bSAndroid Build Coastguard Worker         });
682*08b48e0bSAndroid Build Coastguard Worker 
683*08b48e0bSAndroid Build Coastguard Worker       } else if (afl->mutation[0] != 0) {
684*08b48e0bSAndroid Build Coastguard Worker 
685*08b48e0bSAndroid Build Coastguard Worker         fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation);
686*08b48e0bSAndroid Build Coastguard Worker 
687*08b48e0bSAndroid Build Coastguard Worker       }
688*08b48e0bSAndroid Build Coastguard Worker 
689*08b48e0bSAndroid Build Coastguard Worker #endif
690*08b48e0bSAndroid Build Coastguard Worker 
691*08b48e0bSAndroid Build Coastguard Worker       /* Before saving, we make sure that it's a genuine hang by re-running
692*08b48e0bSAndroid Build Coastguard Worker          the target with a more generous timeout (unless the default timeout
693*08b48e0bSAndroid Build Coastguard Worker          is already generous). */
694*08b48e0bSAndroid Build Coastguard Worker 
695*08b48e0bSAndroid Build Coastguard Worker       if (afl->fsrv.exec_tmout < afl->hang_tmout) {
696*08b48e0bSAndroid Build Coastguard Worker 
697*08b48e0bSAndroid Build Coastguard Worker         u8  new_fault;
698*08b48e0bSAndroid Build Coastguard Worker         u32 tmp_len = write_to_testcase(afl, &mem, len, 0);
699*08b48e0bSAndroid Build Coastguard Worker 
700*08b48e0bSAndroid Build Coastguard Worker         if (likely(tmp_len)) {
701*08b48e0bSAndroid Build Coastguard Worker 
702*08b48e0bSAndroid Build Coastguard Worker           len = tmp_len;
703*08b48e0bSAndroid Build Coastguard Worker 
704*08b48e0bSAndroid Build Coastguard Worker         } else {
705*08b48e0bSAndroid Build Coastguard Worker 
706*08b48e0bSAndroid Build Coastguard Worker           len = write_to_testcase(afl, &mem, len, 1);
707*08b48e0bSAndroid Build Coastguard Worker 
708*08b48e0bSAndroid Build Coastguard Worker         }
709*08b48e0bSAndroid Build Coastguard Worker 
710*08b48e0bSAndroid Build Coastguard Worker         new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
711*08b48e0bSAndroid Build Coastguard Worker         classify_counts(&afl->fsrv);
712*08b48e0bSAndroid Build Coastguard Worker 
713*08b48e0bSAndroid Build Coastguard Worker         /* A corner case that one user reported bumping into: increasing the
714*08b48e0bSAndroid Build Coastguard Worker            timeout actually uncovers a crash. Make sure we don't discard it if
715*08b48e0bSAndroid Build Coastguard Worker            so. */
716*08b48e0bSAndroid Build Coastguard Worker 
717*08b48e0bSAndroid Build Coastguard Worker         if (!afl->stop_soon && new_fault == FSRV_RUN_CRASH) {
718*08b48e0bSAndroid Build Coastguard Worker 
719*08b48e0bSAndroid Build Coastguard Worker           goto keep_as_crash;
720*08b48e0bSAndroid Build Coastguard Worker 
721*08b48e0bSAndroid Build Coastguard Worker         }
722*08b48e0bSAndroid Build Coastguard Worker 
723*08b48e0bSAndroid Build Coastguard Worker         if (afl->stop_soon || new_fault != FSRV_RUN_TMOUT) {
724*08b48e0bSAndroid Build Coastguard Worker 
725*08b48e0bSAndroid Build Coastguard Worker           if (afl->afl_env.afl_keep_timeouts) {
726*08b48e0bSAndroid Build Coastguard Worker 
727*08b48e0bSAndroid Build Coastguard Worker             ++afl->saved_tmouts;
728*08b48e0bSAndroid Build Coastguard Worker             goto save_to_queue;
729*08b48e0bSAndroid Build Coastguard Worker 
730*08b48e0bSAndroid Build Coastguard Worker           } else {
731*08b48e0bSAndroid Build Coastguard Worker 
732*08b48e0bSAndroid Build Coastguard Worker             return keeping;
733*08b48e0bSAndroid Build Coastguard Worker 
734*08b48e0bSAndroid Build Coastguard Worker           }
735*08b48e0bSAndroid Build Coastguard Worker 
736*08b48e0bSAndroid Build Coastguard Worker         }
737*08b48e0bSAndroid Build Coastguard Worker 
738*08b48e0bSAndroid Build Coastguard Worker       }
739*08b48e0bSAndroid Build Coastguard Worker 
740*08b48e0bSAndroid Build Coastguard Worker #ifndef SIMPLE_FILES
741*08b48e0bSAndroid Build Coastguard Worker 
742*08b48e0bSAndroid Build Coastguard Worker       snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir,
743*08b48e0bSAndroid Build Coastguard Worker                afl->saved_hangs,
744*08b48e0bSAndroid Build Coastguard Worker                describe_op(afl, 0, NAME_MAX - strlen("id:000000,")));
745*08b48e0bSAndroid Build Coastguard Worker 
746*08b48e0bSAndroid Build Coastguard Worker #else
747*08b48e0bSAndroid Build Coastguard Worker 
748*08b48e0bSAndroid Build Coastguard Worker       snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir,
749*08b48e0bSAndroid Build Coastguard Worker                afl->saved_hangs);
750*08b48e0bSAndroid Build Coastguard Worker 
751*08b48e0bSAndroid Build Coastguard Worker #endif                                                    /* ^!SIMPLE_FILES */
752*08b48e0bSAndroid Build Coastguard Worker 
753*08b48e0bSAndroid Build Coastguard Worker       ++afl->saved_hangs;
754*08b48e0bSAndroid Build Coastguard Worker 
755*08b48e0bSAndroid Build Coastguard Worker       afl->last_hang_time = get_cur_time();
756*08b48e0bSAndroid Build Coastguard Worker 
757*08b48e0bSAndroid Build Coastguard Worker       break;
758*08b48e0bSAndroid Build Coastguard Worker 
759*08b48e0bSAndroid Build Coastguard Worker     case FSRV_RUN_CRASH:
760*08b48e0bSAndroid Build Coastguard Worker 
761*08b48e0bSAndroid Build Coastguard Worker     keep_as_crash:
762*08b48e0bSAndroid Build Coastguard Worker 
763*08b48e0bSAndroid Build Coastguard Worker       /* This is handled in a manner roughly similar to timeouts,
764*08b48e0bSAndroid Build Coastguard Worker          except for slightly different limits and no need to re-run test
765*08b48e0bSAndroid Build Coastguard Worker          cases. */
766*08b48e0bSAndroid Build Coastguard Worker 
767*08b48e0bSAndroid Build Coastguard Worker       ++afl->total_crashes;
768*08b48e0bSAndroid Build Coastguard Worker 
769*08b48e0bSAndroid Build Coastguard Worker       if (afl->saved_crashes >= KEEP_UNIQUE_CRASH) { return keeping; }
770*08b48e0bSAndroid Build Coastguard Worker 
771*08b48e0bSAndroid Build Coastguard Worker       if (likely(!afl->non_instrumented_mode)) {
772*08b48e0bSAndroid Build Coastguard Worker 
773*08b48e0bSAndroid Build Coastguard Worker         if (unlikely(!classified)) {
774*08b48e0bSAndroid Build Coastguard Worker 
775*08b48e0bSAndroid Build Coastguard Worker           classify_counts(&afl->fsrv);
776*08b48e0bSAndroid Build Coastguard Worker           classified = 1;
777*08b48e0bSAndroid Build Coastguard Worker 
778*08b48e0bSAndroid Build Coastguard Worker         }
779*08b48e0bSAndroid Build Coastguard Worker 
780*08b48e0bSAndroid Build Coastguard Worker         simplify_trace(afl, afl->fsrv.trace_bits);
781*08b48e0bSAndroid Build Coastguard Worker 
782*08b48e0bSAndroid Build Coastguard Worker         if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; }
783*08b48e0bSAndroid Build Coastguard Worker 
784*08b48e0bSAndroid Build Coastguard Worker       }
785*08b48e0bSAndroid Build Coastguard Worker 
786*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(!afl->saved_crashes) &&
787*08b48e0bSAndroid Build Coastguard Worker           (afl->afl_env.afl_no_crash_readme != 1)) {
788*08b48e0bSAndroid Build Coastguard Worker 
789*08b48e0bSAndroid Build Coastguard Worker         write_crash_readme(afl);
790*08b48e0bSAndroid Build Coastguard Worker 
791*08b48e0bSAndroid Build Coastguard Worker       }
792*08b48e0bSAndroid Build Coastguard Worker 
793*08b48e0bSAndroid Build Coastguard Worker #ifndef SIMPLE_FILES
794*08b48e0bSAndroid Build Coastguard Worker 
795*08b48e0bSAndroid Build Coastguard Worker       snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
796*08b48e0bSAndroid Build Coastguard Worker                afl->saved_crashes, afl->fsrv.last_kill_signal,
797*08b48e0bSAndroid Build Coastguard Worker                describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")));
798*08b48e0bSAndroid Build Coastguard Worker 
799*08b48e0bSAndroid Build Coastguard Worker #else
800*08b48e0bSAndroid Build Coastguard Worker 
801*08b48e0bSAndroid Build Coastguard Worker       snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
802*08b48e0bSAndroid Build Coastguard Worker                afl->saved_crashes, afl->fsrv.last_kill_signal);
803*08b48e0bSAndroid Build Coastguard Worker 
804*08b48e0bSAndroid Build Coastguard Worker #endif                                                    /* ^!SIMPLE_FILES */
805*08b48e0bSAndroid Build Coastguard Worker 
806*08b48e0bSAndroid Build Coastguard Worker       ++afl->saved_crashes;
807*08b48e0bSAndroid Build Coastguard Worker #ifdef INTROSPECTION
808*08b48e0bSAndroid Build Coastguard Worker       if (afl->custom_mutators_count && afl->current_custom_fuzz) {
809*08b48e0bSAndroid Build Coastguard Worker 
810*08b48e0bSAndroid Build Coastguard Worker         LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
811*08b48e0bSAndroid Build Coastguard Worker 
812*08b48e0bSAndroid Build Coastguard Worker           if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
813*08b48e0bSAndroid Build Coastguard Worker 
814*08b48e0bSAndroid Build Coastguard Worker             const char *ptr = el->afl_custom_introspection(el->data);
815*08b48e0bSAndroid Build Coastguard Worker 
816*08b48e0bSAndroid Build Coastguard Worker             if (ptr != NULL && *ptr != 0) {
817*08b48e0bSAndroid Build Coastguard Worker 
818*08b48e0bSAndroid Build Coastguard Worker               fprintf(afl->introspection_file, "UNIQUE_CRASH CUSTOM %s = %s\n",
819*08b48e0bSAndroid Build Coastguard Worker                       ptr, afl->queue_top->fname);
820*08b48e0bSAndroid Build Coastguard Worker 
821*08b48e0bSAndroid Build Coastguard Worker             }
822*08b48e0bSAndroid Build Coastguard Worker 
823*08b48e0bSAndroid Build Coastguard Worker           }
824*08b48e0bSAndroid Build Coastguard Worker 
825*08b48e0bSAndroid Build Coastguard Worker         });
826*08b48e0bSAndroid Build Coastguard Worker 
827*08b48e0bSAndroid Build Coastguard Worker       } else if (afl->mutation[0] != 0) {
828*08b48e0bSAndroid Build Coastguard Worker 
829*08b48e0bSAndroid Build Coastguard Worker         fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation);
830*08b48e0bSAndroid Build Coastguard Worker 
831*08b48e0bSAndroid Build Coastguard Worker       }
832*08b48e0bSAndroid Build Coastguard Worker 
833*08b48e0bSAndroid Build Coastguard Worker #endif
834*08b48e0bSAndroid Build Coastguard Worker       if (unlikely(afl->infoexec)) {
835*08b48e0bSAndroid Build Coastguard Worker 
836*08b48e0bSAndroid Build Coastguard Worker         // if the user wants to be informed on new crashes - do that
837*08b48e0bSAndroid Build Coastguard Worker #if !TARGET_OS_IPHONE
838*08b48e0bSAndroid Build Coastguard Worker         // we dont care if system errors, but we dont want a
839*08b48e0bSAndroid Build Coastguard Worker         // compiler warning either
840*08b48e0bSAndroid Build Coastguard Worker         // See
841*08b48e0bSAndroid Build Coastguard Worker         // https://stackoverflow.com/questions/11888594/ignoring-return-values-in-c
842*08b48e0bSAndroid Build Coastguard Worker         (void)(system(afl->infoexec) + 1);
843*08b48e0bSAndroid Build Coastguard Worker #else
844*08b48e0bSAndroid Build Coastguard Worker         WARNF("command execution unsupported");
845*08b48e0bSAndroid Build Coastguard Worker #endif
846*08b48e0bSAndroid Build Coastguard Worker 
847*08b48e0bSAndroid Build Coastguard Worker       }
848*08b48e0bSAndroid Build Coastguard Worker 
849*08b48e0bSAndroid Build Coastguard Worker       afl->last_crash_time = get_cur_time();
850*08b48e0bSAndroid Build Coastguard Worker       afl->last_crash_execs = afl->fsrv.total_execs;
851*08b48e0bSAndroid Build Coastguard Worker 
852*08b48e0bSAndroid Build Coastguard Worker       break;
853*08b48e0bSAndroid Build Coastguard Worker 
854*08b48e0bSAndroid Build Coastguard Worker     case FSRV_RUN_ERROR:
855*08b48e0bSAndroid Build Coastguard Worker       FATAL("Unable to execute target application");
856*08b48e0bSAndroid Build Coastguard Worker 
857*08b48e0bSAndroid Build Coastguard Worker     default:
858*08b48e0bSAndroid Build Coastguard Worker       return keeping;
859*08b48e0bSAndroid Build Coastguard Worker 
860*08b48e0bSAndroid Build Coastguard Worker   }
861*08b48e0bSAndroid Build Coastguard Worker 
862*08b48e0bSAndroid Build Coastguard Worker   /* If we're here, we apparently want to save the crash or hang
863*08b48e0bSAndroid Build Coastguard Worker      test case, too. */
864*08b48e0bSAndroid Build Coastguard Worker 
865*08b48e0bSAndroid Build Coastguard Worker   fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
866*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); }
867*08b48e0bSAndroid Build Coastguard Worker   ck_write(fd, mem, len, fn);
868*08b48e0bSAndroid Build Coastguard Worker   close(fd);
869*08b48e0bSAndroid Build Coastguard Worker 
870*08b48e0bSAndroid Build Coastguard Worker #ifdef __linux__
871*08b48e0bSAndroid Build Coastguard Worker   if (afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) {
872*08b48e0bSAndroid Build Coastguard Worker 
873*08b48e0bSAndroid Build Coastguard Worker     u8 fn_log[PATH_MAX];
874*08b48e0bSAndroid Build Coastguard Worker 
875*08b48e0bSAndroid Build Coastguard Worker     (void)(snprintf(fn_log, PATH_MAX, "%s.log", fn) + 1);
876*08b48e0bSAndroid Build Coastguard Worker     fd = open(fn_log, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
877*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn_log); }
878*08b48e0bSAndroid Build Coastguard Worker 
879*08b48e0bSAndroid Build Coastguard Worker     u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string(
880*08b48e0bSAndroid Build Coastguard Worker         afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string,
881*08b48e0bSAndroid Build Coastguard Worker         afl->fsrv.nyx_aux_string_len);
882*08b48e0bSAndroid Build Coastguard Worker 
883*08b48e0bSAndroid Build Coastguard Worker     ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, fn_log);
884*08b48e0bSAndroid Build Coastguard Worker     close(fd);
885*08b48e0bSAndroid Build Coastguard Worker 
886*08b48e0bSAndroid Build Coastguard Worker   }
887*08b48e0bSAndroid Build Coastguard Worker 
888*08b48e0bSAndroid Build Coastguard Worker #endif
889*08b48e0bSAndroid Build Coastguard Worker 
890*08b48e0bSAndroid Build Coastguard Worker   return keeping;
891*08b48e0bSAndroid Build Coastguard Worker 
892*08b48e0bSAndroid Build Coastguard Worker }
893*08b48e0bSAndroid Build Coastguard Worker 
894