xref: /aosp_15_r20/external/AFLplusplus/src/afl-fuzz-extras.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker    american fuzzy lop++ - extras relates 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 
28*08b48e0bSAndroid Build Coastguard Worker /* helper function for auto_extras qsort */
compare_auto_extras_len(const void * ae1,const void * ae2)29*08b48e0bSAndroid Build Coastguard Worker static int compare_auto_extras_len(const void *ae1, const void *ae2) {
30*08b48e0bSAndroid Build Coastguard Worker 
31*08b48e0bSAndroid Build Coastguard Worker   return ((struct auto_extra_data *)ae1)->len -
32*08b48e0bSAndroid Build Coastguard Worker          ((struct auto_extra_data *)ae2)->len;
33*08b48e0bSAndroid Build Coastguard Worker 
34*08b48e0bSAndroid Build Coastguard Worker }
35*08b48e0bSAndroid Build Coastguard Worker 
36*08b48e0bSAndroid Build Coastguard Worker /* descending order */
37*08b48e0bSAndroid Build Coastguard Worker 
compare_auto_extras_use_d(const void * ae1,const void * ae2)38*08b48e0bSAndroid Build Coastguard Worker static int compare_auto_extras_use_d(const void *ae1, const void *ae2) {
39*08b48e0bSAndroid Build Coastguard Worker 
40*08b48e0bSAndroid Build Coastguard Worker   return ((struct auto_extra_data *)ae2)->hit_cnt -
41*08b48e0bSAndroid Build Coastguard Worker          ((struct auto_extra_data *)ae1)->hit_cnt;
42*08b48e0bSAndroid Build Coastguard Worker 
43*08b48e0bSAndroid Build Coastguard Worker }
44*08b48e0bSAndroid Build Coastguard Worker 
45*08b48e0bSAndroid Build Coastguard Worker /* Helper function for load_extras. */
46*08b48e0bSAndroid Build Coastguard Worker 
compare_extras_len(const void * e1,const void * e2)47*08b48e0bSAndroid Build Coastguard Worker static int compare_extras_len(const void *e1, const void *e2) {
48*08b48e0bSAndroid Build Coastguard Worker 
49*08b48e0bSAndroid Build Coastguard Worker   return ((struct extra_data *)e1)->len - ((struct extra_data *)e2)->len;
50*08b48e0bSAndroid Build Coastguard Worker 
51*08b48e0bSAndroid Build Coastguard Worker }
52*08b48e0bSAndroid Build Coastguard Worker 
53*08b48e0bSAndroid Build Coastguard Worker /* Read extras from a file, sort by size. */
54*08b48e0bSAndroid Build Coastguard Worker 
load_extras_file(afl_state_t * afl,u8 * fname,u32 * min_len,u32 * max_len,u32 dict_level)55*08b48e0bSAndroid Build Coastguard Worker void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
56*08b48e0bSAndroid Build Coastguard Worker                       u32 dict_level) {
57*08b48e0bSAndroid Build Coastguard Worker 
58*08b48e0bSAndroid Build Coastguard Worker   FILE *f;
59*08b48e0bSAndroid Build Coastguard Worker   u8    buf[MAX_LINE];
60*08b48e0bSAndroid Build Coastguard Worker   u8   *lptr;
61*08b48e0bSAndroid Build Coastguard Worker   u32   cur_line = 0;
62*08b48e0bSAndroid Build Coastguard Worker 
63*08b48e0bSAndroid Build Coastguard Worker   u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
64*08b48e0bSAndroid Build Coastguard Worker 
65*08b48e0bSAndroid Build Coastguard Worker   f = fopen(fname, "r");
66*08b48e0bSAndroid Build Coastguard Worker 
67*08b48e0bSAndroid Build Coastguard Worker   if (!f) { PFATAL("Unable to open '%s'", fname); }
68*08b48e0bSAndroid Build Coastguard Worker 
69*08b48e0bSAndroid Build Coastguard Worker   while ((lptr = fgets(buf, MAX_LINE, f))) {
70*08b48e0bSAndroid Build Coastguard Worker 
71*08b48e0bSAndroid Build Coastguard Worker     u8 *rptr, *wptr;
72*08b48e0bSAndroid Build Coastguard Worker     u32 klen = 0;
73*08b48e0bSAndroid Build Coastguard Worker 
74*08b48e0bSAndroid Build Coastguard Worker     ++cur_line;
75*08b48e0bSAndroid Build Coastguard Worker 
76*08b48e0bSAndroid Build Coastguard Worker     /* Trim on left and right. */
77*08b48e0bSAndroid Build Coastguard Worker 
78*08b48e0bSAndroid Build Coastguard Worker     while (isspace(*lptr)) {
79*08b48e0bSAndroid Build Coastguard Worker 
80*08b48e0bSAndroid Build Coastguard Worker       ++lptr;
81*08b48e0bSAndroid Build Coastguard Worker 
82*08b48e0bSAndroid Build Coastguard Worker     }
83*08b48e0bSAndroid Build Coastguard Worker 
84*08b48e0bSAndroid Build Coastguard Worker     rptr = lptr + strlen(lptr) - 1;
85*08b48e0bSAndroid Build Coastguard Worker     while (rptr >= lptr && isspace(*rptr)) {
86*08b48e0bSAndroid Build Coastguard Worker 
87*08b48e0bSAndroid Build Coastguard Worker       --rptr;
88*08b48e0bSAndroid Build Coastguard Worker 
89*08b48e0bSAndroid Build Coastguard Worker     }
90*08b48e0bSAndroid Build Coastguard Worker 
91*08b48e0bSAndroid Build Coastguard Worker     ++rptr;
92*08b48e0bSAndroid Build Coastguard Worker     *rptr = 0;
93*08b48e0bSAndroid Build Coastguard Worker 
94*08b48e0bSAndroid Build Coastguard Worker     /* Skip empty lines and comments. */
95*08b48e0bSAndroid Build Coastguard Worker 
96*08b48e0bSAndroid Build Coastguard Worker     if (!*lptr || *lptr == '#') { continue; }
97*08b48e0bSAndroid Build Coastguard Worker 
98*08b48e0bSAndroid Build Coastguard Worker     /* All other lines must end with '"', which we can consume. */
99*08b48e0bSAndroid Build Coastguard Worker 
100*08b48e0bSAndroid Build Coastguard Worker     --rptr;
101*08b48e0bSAndroid Build Coastguard Worker 
102*08b48e0bSAndroid Build Coastguard Worker     if (rptr < lptr || *rptr != '"') {
103*08b48e0bSAndroid Build Coastguard Worker 
104*08b48e0bSAndroid Build Coastguard Worker       WARNF("Malformed name=\"value\" pair in line %u.", cur_line);
105*08b48e0bSAndroid Build Coastguard Worker       continue;
106*08b48e0bSAndroid Build Coastguard Worker 
107*08b48e0bSAndroid Build Coastguard Worker     }
108*08b48e0bSAndroid Build Coastguard Worker 
109*08b48e0bSAndroid Build Coastguard Worker     *rptr = 0;
110*08b48e0bSAndroid Build Coastguard Worker 
111*08b48e0bSAndroid Build Coastguard Worker     /* Skip alphanumerics and dashes (label). */
112*08b48e0bSAndroid Build Coastguard Worker 
113*08b48e0bSAndroid Build Coastguard Worker     while (isalnum(*lptr) || *lptr == '_') {
114*08b48e0bSAndroid Build Coastguard Worker 
115*08b48e0bSAndroid Build Coastguard Worker       ++lptr;
116*08b48e0bSAndroid Build Coastguard Worker 
117*08b48e0bSAndroid Build Coastguard Worker     }
118*08b48e0bSAndroid Build Coastguard Worker 
119*08b48e0bSAndroid Build Coastguard Worker     /* If @number follows, parse that. */
120*08b48e0bSAndroid Build Coastguard Worker 
121*08b48e0bSAndroid Build Coastguard Worker     if (*lptr == '@') {
122*08b48e0bSAndroid Build Coastguard Worker 
123*08b48e0bSAndroid Build Coastguard Worker       ++lptr;
124*08b48e0bSAndroid Build Coastguard Worker       if (atoi(lptr) > (s32)dict_level) { continue; }
125*08b48e0bSAndroid Build Coastguard Worker       while (isdigit(*lptr)) {
126*08b48e0bSAndroid Build Coastguard Worker 
127*08b48e0bSAndroid Build Coastguard Worker         ++lptr;
128*08b48e0bSAndroid Build Coastguard Worker 
129*08b48e0bSAndroid Build Coastguard Worker       }
130*08b48e0bSAndroid Build Coastguard Worker 
131*08b48e0bSAndroid Build Coastguard Worker     }
132*08b48e0bSAndroid Build Coastguard Worker 
133*08b48e0bSAndroid Build Coastguard Worker     /* Skip [number] */
134*08b48e0bSAndroid Build Coastguard Worker 
135*08b48e0bSAndroid Build Coastguard Worker     if (*lptr == '[') {
136*08b48e0bSAndroid Build Coastguard Worker 
137*08b48e0bSAndroid Build Coastguard Worker       do {
138*08b48e0bSAndroid Build Coastguard Worker 
139*08b48e0bSAndroid Build Coastguard Worker         ++lptr;
140*08b48e0bSAndroid Build Coastguard Worker 
141*08b48e0bSAndroid Build Coastguard Worker       } while (*lptr >= '0' && *lptr <= '9');
142*08b48e0bSAndroid Build Coastguard Worker 
143*08b48e0bSAndroid Build Coastguard Worker       if (*lptr == ']') { ++lptr; }
144*08b48e0bSAndroid Build Coastguard Worker 
145*08b48e0bSAndroid Build Coastguard Worker     }
146*08b48e0bSAndroid Build Coastguard Worker 
147*08b48e0bSAndroid Build Coastguard Worker     /* Skip whitespace and = signs. */
148*08b48e0bSAndroid Build Coastguard Worker 
149*08b48e0bSAndroid Build Coastguard Worker     while (isspace(*lptr) || *lptr == '=') {
150*08b48e0bSAndroid Build Coastguard Worker 
151*08b48e0bSAndroid Build Coastguard Worker       ++lptr;
152*08b48e0bSAndroid Build Coastguard Worker 
153*08b48e0bSAndroid Build Coastguard Worker     }
154*08b48e0bSAndroid Build Coastguard Worker 
155*08b48e0bSAndroid Build Coastguard Worker     /* Consume opening '"'. */
156*08b48e0bSAndroid Build Coastguard Worker 
157*08b48e0bSAndroid Build Coastguard Worker     if (*lptr != '"') {
158*08b48e0bSAndroid Build Coastguard Worker 
159*08b48e0bSAndroid Build Coastguard Worker       WARNF("Malformed name=\"keyword\" pair in line %u.", cur_line);
160*08b48e0bSAndroid Build Coastguard Worker       continue;
161*08b48e0bSAndroid Build Coastguard Worker 
162*08b48e0bSAndroid Build Coastguard Worker     }
163*08b48e0bSAndroid Build Coastguard Worker 
164*08b48e0bSAndroid Build Coastguard Worker     ++lptr;
165*08b48e0bSAndroid Build Coastguard Worker 
166*08b48e0bSAndroid Build Coastguard Worker     if (!*lptr) {
167*08b48e0bSAndroid Build Coastguard Worker 
168*08b48e0bSAndroid Build Coastguard Worker       WARNF("Empty keyword in line %u.", cur_line);
169*08b48e0bSAndroid Build Coastguard Worker       continue;
170*08b48e0bSAndroid Build Coastguard Worker 
171*08b48e0bSAndroid Build Coastguard Worker     }
172*08b48e0bSAndroid Build Coastguard Worker 
173*08b48e0bSAndroid Build Coastguard Worker     /* Okay, let's allocate memory and copy data between "...", handling
174*08b48e0bSAndroid Build Coastguard Worker        \xNN escaping, \\, and \". */
175*08b48e0bSAndroid Build Coastguard Worker 
176*08b48e0bSAndroid Build Coastguard Worker     afl->extras =
177*08b48e0bSAndroid Build Coastguard Worker         afl_realloc((void **)&afl->extras,
178*08b48e0bSAndroid Build Coastguard Worker                     (afl->extras_cnt + 1) * sizeof(struct extra_data));
179*08b48e0bSAndroid Build Coastguard Worker     char *hexdigits = "0123456789abcdef";
180*08b48e0bSAndroid Build Coastguard Worker 
181*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(!afl->extras)) { PFATAL("alloc"); }
182*08b48e0bSAndroid Build Coastguard Worker 
183*08b48e0bSAndroid Build Coastguard Worker     wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
184*08b48e0bSAndroid Build Coastguard Worker 
185*08b48e0bSAndroid Build Coastguard Worker     if (!wptr) { PFATAL("no mem for data"); }
186*08b48e0bSAndroid Build Coastguard Worker 
187*08b48e0bSAndroid Build Coastguard Worker     while (*lptr) {
188*08b48e0bSAndroid Build Coastguard Worker 
189*08b48e0bSAndroid Build Coastguard Worker       switch (*lptr) {
190*08b48e0bSAndroid Build Coastguard Worker 
191*08b48e0bSAndroid Build Coastguard Worker         case 1 ... 31:
192*08b48e0bSAndroid Build Coastguard Worker         case 128 ... 255:
193*08b48e0bSAndroid Build Coastguard Worker           WARNF("Non-printable characters in line %u.", cur_line);
194*08b48e0bSAndroid Build Coastguard Worker           ++lptr;
195*08b48e0bSAndroid Build Coastguard Worker           continue;
196*08b48e0bSAndroid Build Coastguard Worker           break;
197*08b48e0bSAndroid Build Coastguard Worker 
198*08b48e0bSAndroid Build Coastguard Worker         case '\\':
199*08b48e0bSAndroid Build Coastguard Worker 
200*08b48e0bSAndroid Build Coastguard Worker           ++lptr;
201*08b48e0bSAndroid Build Coastguard Worker 
202*08b48e0bSAndroid Build Coastguard Worker           if (*lptr == '\\' || *lptr == '"') {
203*08b48e0bSAndroid Build Coastguard Worker 
204*08b48e0bSAndroid Build Coastguard Worker             *(wptr++) = *(lptr++);
205*08b48e0bSAndroid Build Coastguard Worker             klen++;
206*08b48e0bSAndroid Build Coastguard Worker             break;
207*08b48e0bSAndroid Build Coastguard Worker 
208*08b48e0bSAndroid Build Coastguard Worker           }
209*08b48e0bSAndroid Build Coastguard Worker 
210*08b48e0bSAndroid Build Coastguard Worker           if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) {
211*08b48e0bSAndroid Build Coastguard Worker 
212*08b48e0bSAndroid Build Coastguard Worker             WARNF("Invalid escaping (not \\xNN) in line %u.", cur_line);
213*08b48e0bSAndroid Build Coastguard Worker             continue;
214*08b48e0bSAndroid Build Coastguard Worker 
215*08b48e0bSAndroid Build Coastguard Worker           }
216*08b48e0bSAndroid Build Coastguard Worker 
217*08b48e0bSAndroid Build Coastguard Worker           *(wptr++) = ((strchr(hexdigits, tolower(lptr[1])) - hexdigits) << 4) |
218*08b48e0bSAndroid Build Coastguard Worker                       (strchr(hexdigits, tolower(lptr[2])) - hexdigits);
219*08b48e0bSAndroid Build Coastguard Worker 
220*08b48e0bSAndroid Build Coastguard Worker           lptr += 3;
221*08b48e0bSAndroid Build Coastguard Worker           ++klen;
222*08b48e0bSAndroid Build Coastguard Worker 
223*08b48e0bSAndroid Build Coastguard Worker           break;
224*08b48e0bSAndroid Build Coastguard Worker 
225*08b48e0bSAndroid Build Coastguard Worker         default:
226*08b48e0bSAndroid Build Coastguard Worker           *(wptr++) = *(lptr++);
227*08b48e0bSAndroid Build Coastguard Worker           ++klen;
228*08b48e0bSAndroid Build Coastguard Worker 
229*08b48e0bSAndroid Build Coastguard Worker       }
230*08b48e0bSAndroid Build Coastguard Worker 
231*08b48e0bSAndroid Build Coastguard Worker     }
232*08b48e0bSAndroid Build Coastguard Worker 
233*08b48e0bSAndroid Build Coastguard Worker     afl->extras[afl->extras_cnt].len = klen;
234*08b48e0bSAndroid Build Coastguard Worker 
235*08b48e0bSAndroid Build Coastguard Worker     if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE) {
236*08b48e0bSAndroid Build Coastguard Worker 
237*08b48e0bSAndroid Build Coastguard Worker       WARNF(
238*08b48e0bSAndroid Build Coastguard Worker           "Keyword too big in line %u (%s, limit is %s)", cur_line,
239*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen),
240*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
241*08b48e0bSAndroid Build Coastguard Worker       continue;
242*08b48e0bSAndroid Build Coastguard Worker 
243*08b48e0bSAndroid Build Coastguard Worker     }
244*08b48e0bSAndroid Build Coastguard Worker 
245*08b48e0bSAndroid Build Coastguard Worker     if (*min_len > klen) { *min_len = klen; }
246*08b48e0bSAndroid Build Coastguard Worker     if (*max_len < klen) { *max_len = klen; }
247*08b48e0bSAndroid Build Coastguard Worker 
248*08b48e0bSAndroid Build Coastguard Worker     ++afl->extras_cnt;
249*08b48e0bSAndroid Build Coastguard Worker 
250*08b48e0bSAndroid Build Coastguard Worker   }
251*08b48e0bSAndroid Build Coastguard Worker 
252*08b48e0bSAndroid Build Coastguard Worker   fclose(f);
253*08b48e0bSAndroid Build Coastguard Worker 
254*08b48e0bSAndroid Build Coastguard Worker }
255*08b48e0bSAndroid Build Coastguard Worker 
extras_check_and_sort(afl_state_t * afl,u32 min_len,u32 max_len,u8 * dir)256*08b48e0bSAndroid Build Coastguard Worker static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
257*08b48e0bSAndroid Build Coastguard Worker                                   u8 *dir) {
258*08b48e0bSAndroid Build Coastguard Worker 
259*08b48e0bSAndroid Build Coastguard Worker   u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
260*08b48e0bSAndroid Build Coastguard Worker 
261*08b48e0bSAndroid Build Coastguard Worker   if (!afl->extras_cnt) {
262*08b48e0bSAndroid Build Coastguard Worker 
263*08b48e0bSAndroid Build Coastguard Worker     WARNF("No usable data in '%s'", dir);
264*08b48e0bSAndroid Build Coastguard Worker     return;
265*08b48e0bSAndroid Build Coastguard Worker 
266*08b48e0bSAndroid Build Coastguard Worker   }
267*08b48e0bSAndroid Build Coastguard Worker 
268*08b48e0bSAndroid Build Coastguard Worker   qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
269*08b48e0bSAndroid Build Coastguard Worker         compare_extras_len);
270*08b48e0bSAndroid Build Coastguard Worker 
271*08b48e0bSAndroid Build Coastguard Worker   ACTF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt,
272*08b48e0bSAndroid Build Coastguard Worker        stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len),
273*08b48e0bSAndroid Build Coastguard Worker        stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len));
274*08b48e0bSAndroid Build Coastguard Worker 
275*08b48e0bSAndroid Build Coastguard Worker   if (max_len > 32) {
276*08b48e0bSAndroid Build Coastguard Worker 
277*08b48e0bSAndroid Build Coastguard Worker     WARNF("Some tokens are relatively large (%s) - consider trimming.",
278*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len));
279*08b48e0bSAndroid Build Coastguard Worker 
280*08b48e0bSAndroid Build Coastguard Worker   }
281*08b48e0bSAndroid Build Coastguard Worker 
282*08b48e0bSAndroid Build Coastguard Worker   if (afl->extras_cnt > afl->max_det_extras) {
283*08b48e0bSAndroid Build Coastguard Worker 
284*08b48e0bSAndroid Build Coastguard Worker     WARNF("More than %u tokens - will use them probabilistically.",
285*08b48e0bSAndroid Build Coastguard Worker           afl->max_det_extras);
286*08b48e0bSAndroid Build Coastguard Worker 
287*08b48e0bSAndroid Build Coastguard Worker   }
288*08b48e0bSAndroid Build Coastguard Worker 
289*08b48e0bSAndroid Build Coastguard Worker }
290*08b48e0bSAndroid Build Coastguard Worker 
291*08b48e0bSAndroid Build Coastguard Worker /* Read extras from the extras directory and sort them by size. */
292*08b48e0bSAndroid Build Coastguard Worker 
load_extras(afl_state_t * afl,u8 * dir)293*08b48e0bSAndroid Build Coastguard Worker void load_extras(afl_state_t *afl, u8 *dir) {
294*08b48e0bSAndroid Build Coastguard Worker 
295*08b48e0bSAndroid Build Coastguard Worker   DIR           *d;
296*08b48e0bSAndroid Build Coastguard Worker   struct dirent *de;
297*08b48e0bSAndroid Build Coastguard Worker   u32            min_len = MAX_DICT_FILE, max_len = 0, dict_level = 0;
298*08b48e0bSAndroid Build Coastguard Worker   u8            *x;
299*08b48e0bSAndroid Build Coastguard Worker 
300*08b48e0bSAndroid Build Coastguard Worker   u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
301*08b48e0bSAndroid Build Coastguard Worker 
302*08b48e0bSAndroid Build Coastguard Worker   /* If the name ends with @, extract level and continue. */
303*08b48e0bSAndroid Build Coastguard Worker 
304*08b48e0bSAndroid Build Coastguard Worker   if ((x = strchr(dir, '@'))) {
305*08b48e0bSAndroid Build Coastguard Worker 
306*08b48e0bSAndroid Build Coastguard Worker     *x = 0;
307*08b48e0bSAndroid Build Coastguard Worker     dict_level = atoi(x + 1);
308*08b48e0bSAndroid Build Coastguard Worker 
309*08b48e0bSAndroid Build Coastguard Worker   }
310*08b48e0bSAndroid Build Coastguard Worker 
311*08b48e0bSAndroid Build Coastguard Worker   ACTF("Loading extra dictionary from '%s' (level %u)...", dir, dict_level);
312*08b48e0bSAndroid Build Coastguard Worker 
313*08b48e0bSAndroid Build Coastguard Worker   d = opendir(dir);
314*08b48e0bSAndroid Build Coastguard Worker 
315*08b48e0bSAndroid Build Coastguard Worker   if (!d) {
316*08b48e0bSAndroid Build Coastguard Worker 
317*08b48e0bSAndroid Build Coastguard Worker     if (errno == ENOTDIR) {
318*08b48e0bSAndroid Build Coastguard Worker 
319*08b48e0bSAndroid Build Coastguard Worker       load_extras_file(afl, dir, &min_len, &max_len, dict_level);
320*08b48e0bSAndroid Build Coastguard Worker       extras_check_and_sort(afl, min_len, max_len, dir);
321*08b48e0bSAndroid Build Coastguard Worker       return;
322*08b48e0bSAndroid Build Coastguard Worker 
323*08b48e0bSAndroid Build Coastguard Worker     }
324*08b48e0bSAndroid Build Coastguard Worker 
325*08b48e0bSAndroid Build Coastguard Worker     PFATAL("Unable to open '%s'", dir);
326*08b48e0bSAndroid Build Coastguard Worker 
327*08b48e0bSAndroid Build Coastguard Worker   }
328*08b48e0bSAndroid Build Coastguard Worker 
329*08b48e0bSAndroid Build Coastguard Worker   if (x) { FATAL("Dictionary levels not supported for directories."); }
330*08b48e0bSAndroid Build Coastguard Worker 
331*08b48e0bSAndroid Build Coastguard Worker   while ((de = readdir(d))) {
332*08b48e0bSAndroid Build Coastguard Worker 
333*08b48e0bSAndroid Build Coastguard Worker     struct stat st;
334*08b48e0bSAndroid Build Coastguard Worker     u8         *fn = alloc_printf("%s/%s", dir, de->d_name);
335*08b48e0bSAndroid Build Coastguard Worker     s32         fd;
336*08b48e0bSAndroid Build Coastguard Worker 
337*08b48e0bSAndroid Build Coastguard Worker     if (lstat(fn, &st) || access(fn, R_OK)) {
338*08b48e0bSAndroid Build Coastguard Worker 
339*08b48e0bSAndroid Build Coastguard Worker       PFATAL("Unable to access '%s'", fn);
340*08b48e0bSAndroid Build Coastguard Worker 
341*08b48e0bSAndroid Build Coastguard Worker     }
342*08b48e0bSAndroid Build Coastguard Worker 
343*08b48e0bSAndroid Build Coastguard Worker     /* This also takes care of . and .. */
344*08b48e0bSAndroid Build Coastguard Worker     if (!S_ISREG(st.st_mode) || !st.st_size) {
345*08b48e0bSAndroid Build Coastguard Worker 
346*08b48e0bSAndroid Build Coastguard Worker       ck_free(fn);
347*08b48e0bSAndroid Build Coastguard Worker       continue;
348*08b48e0bSAndroid Build Coastguard Worker 
349*08b48e0bSAndroid Build Coastguard Worker     }
350*08b48e0bSAndroid Build Coastguard Worker 
351*08b48e0bSAndroid Build Coastguard Worker     if (st.st_size > MAX_DICT_FILE) {
352*08b48e0bSAndroid Build Coastguard Worker 
353*08b48e0bSAndroid Build Coastguard Worker       WARNF(
354*08b48e0bSAndroid Build Coastguard Worker           "Extra '%s' is too big (%s, limit is %s)", fn,
355*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
356*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
357*08b48e0bSAndroid Build Coastguard Worker       continue;
358*08b48e0bSAndroid Build Coastguard Worker 
359*08b48e0bSAndroid Build Coastguard Worker     }
360*08b48e0bSAndroid Build Coastguard Worker 
361*08b48e0bSAndroid Build Coastguard Worker     if (min_len > st.st_size) { min_len = st.st_size; }
362*08b48e0bSAndroid Build Coastguard Worker     if (max_len < st.st_size) { max_len = st.st_size; }
363*08b48e0bSAndroid Build Coastguard Worker 
364*08b48e0bSAndroid Build Coastguard Worker     afl->extras =
365*08b48e0bSAndroid Build Coastguard Worker         afl_realloc((void **)&afl->extras,
366*08b48e0bSAndroid Build Coastguard Worker                     (afl->extras_cnt + 1) * sizeof(struct extra_data));
367*08b48e0bSAndroid Build Coastguard Worker     if (unlikely(!afl->extras)) { PFATAL("alloc"); }
368*08b48e0bSAndroid Build Coastguard Worker 
369*08b48e0bSAndroid Build Coastguard Worker     afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size);
370*08b48e0bSAndroid Build Coastguard Worker     afl->extras[afl->extras_cnt].len = st.st_size;
371*08b48e0bSAndroid Build Coastguard Worker 
372*08b48e0bSAndroid Build Coastguard Worker     fd = open(fn, O_RDONLY);
373*08b48e0bSAndroid Build Coastguard Worker 
374*08b48e0bSAndroid Build Coastguard Worker     if (fd < 0) { PFATAL("Unable to open '%s'", fn); }
375*08b48e0bSAndroid Build Coastguard Worker 
376*08b48e0bSAndroid Build Coastguard Worker     ck_read(fd, afl->extras[afl->extras_cnt].data, st.st_size, fn);
377*08b48e0bSAndroid Build Coastguard Worker 
378*08b48e0bSAndroid Build Coastguard Worker     close(fd);
379*08b48e0bSAndroid Build Coastguard Worker     ck_free(fn);
380*08b48e0bSAndroid Build Coastguard Worker 
381*08b48e0bSAndroid Build Coastguard Worker     ++afl->extras_cnt;
382*08b48e0bSAndroid Build Coastguard Worker 
383*08b48e0bSAndroid Build Coastguard Worker   }
384*08b48e0bSAndroid Build Coastguard Worker 
385*08b48e0bSAndroid Build Coastguard Worker   closedir(d);
386*08b48e0bSAndroid Build Coastguard Worker 
387*08b48e0bSAndroid Build Coastguard Worker   extras_check_and_sort(afl, min_len, max_len, dir);
388*08b48e0bSAndroid Build Coastguard Worker 
389*08b48e0bSAndroid Build Coastguard Worker }
390*08b48e0bSAndroid Build Coastguard Worker 
391*08b48e0bSAndroid Build Coastguard Worker /* Helper function for maybe_add_auto(afl, ) */
392*08b48e0bSAndroid Build Coastguard Worker 
memcmp_nocase(u8 * m1,u8 * m2,u32 len)393*08b48e0bSAndroid Build Coastguard Worker static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
394*08b48e0bSAndroid Build Coastguard Worker 
395*08b48e0bSAndroid Build Coastguard Worker   while (len--) {
396*08b48e0bSAndroid Build Coastguard Worker 
397*08b48e0bSAndroid Build Coastguard Worker     if (tolower(*(m1++)) ^ tolower(*(m2++))) { return 1; }
398*08b48e0bSAndroid Build Coastguard Worker 
399*08b48e0bSAndroid Build Coastguard Worker   }
400*08b48e0bSAndroid Build Coastguard Worker 
401*08b48e0bSAndroid Build Coastguard Worker   return 0;
402*08b48e0bSAndroid Build Coastguard Worker 
403*08b48e0bSAndroid Build Coastguard Worker }
404*08b48e0bSAndroid Build Coastguard Worker 
405*08b48e0bSAndroid Build Coastguard Worker /* add an extra/dict/token - no checks performed, no sorting */
406*08b48e0bSAndroid Build Coastguard Worker 
add_extra_nocheck(afl_state_t * afl,u8 * mem,u32 len)407*08b48e0bSAndroid Build Coastguard Worker static void add_extra_nocheck(afl_state_t *afl, u8 *mem, u32 len) {
408*08b48e0bSAndroid Build Coastguard Worker 
409*08b48e0bSAndroid Build Coastguard Worker   afl->extras = afl_realloc((void **)&afl->extras,
410*08b48e0bSAndroid Build Coastguard Worker                             (afl->extras_cnt + 1) * sizeof(struct extra_data));
411*08b48e0bSAndroid Build Coastguard Worker 
412*08b48e0bSAndroid Build Coastguard Worker   if (unlikely(!afl->extras)) { PFATAL("alloc"); }
413*08b48e0bSAndroid Build Coastguard Worker 
414*08b48e0bSAndroid Build Coastguard Worker   afl->extras[afl->extras_cnt].data = ck_alloc(len);
415*08b48e0bSAndroid Build Coastguard Worker   afl->extras[afl->extras_cnt].len = len;
416*08b48e0bSAndroid Build Coastguard Worker   memcpy(afl->extras[afl->extras_cnt].data, mem, len);
417*08b48e0bSAndroid Build Coastguard Worker   afl->extras_cnt++;
418*08b48e0bSAndroid Build Coastguard Worker 
419*08b48e0bSAndroid Build Coastguard Worker   /* We only want to print this once */
420*08b48e0bSAndroid Build Coastguard Worker 
421*08b48e0bSAndroid Build Coastguard Worker   if (afl->extras_cnt == afl->max_det_extras + 1) {
422*08b48e0bSAndroid Build Coastguard Worker 
423*08b48e0bSAndroid Build Coastguard Worker     WARNF("More than %u tokens - will use them probabilistically.",
424*08b48e0bSAndroid Build Coastguard Worker           afl->max_det_extras);
425*08b48e0bSAndroid Build Coastguard Worker 
426*08b48e0bSAndroid Build Coastguard Worker   }
427*08b48e0bSAndroid Build Coastguard Worker 
428*08b48e0bSAndroid Build Coastguard Worker }
429*08b48e0bSAndroid Build Coastguard Worker 
430*08b48e0bSAndroid Build Coastguard Worker /* Sometimes strings in input is transformed to unicode internally, so for
431*08b48e0bSAndroid Build Coastguard Worker    fuzzing we should attempt to de-unicode if it looks like simple unicode */
432*08b48e0bSAndroid Build Coastguard Worker 
deunicode_extras(afl_state_t * afl)433*08b48e0bSAndroid Build Coastguard Worker void deunicode_extras(afl_state_t *afl) {
434*08b48e0bSAndroid Build Coastguard Worker 
435*08b48e0bSAndroid Build Coastguard Worker   if (!afl->extras_cnt) return;
436*08b48e0bSAndroid Build Coastguard Worker 
437*08b48e0bSAndroid Build Coastguard Worker   u32 i, j, orig_cnt = afl->extras_cnt;
438*08b48e0bSAndroid Build Coastguard Worker   u8  buf[64];
439*08b48e0bSAndroid Build Coastguard Worker 
440*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < orig_cnt; ++i) {
441*08b48e0bSAndroid Build Coastguard Worker 
442*08b48e0bSAndroid Build Coastguard Worker     if (afl->extras[i].len < 6 || afl->extras[i].len > 64 ||
443*08b48e0bSAndroid Build Coastguard Worker         afl->extras[i].len % 2) {
444*08b48e0bSAndroid Build Coastguard Worker 
445*08b48e0bSAndroid Build Coastguard Worker       continue;
446*08b48e0bSAndroid Build Coastguard Worker 
447*08b48e0bSAndroid Build Coastguard Worker     }
448*08b48e0bSAndroid Build Coastguard Worker 
449*08b48e0bSAndroid Build Coastguard Worker     u32 k = 0, z1 = 0, z2 = 0, z3 = 0, z4 = 0, half = afl->extras[i].len >> 1;
450*08b48e0bSAndroid Build Coastguard Worker     u32 quarter = half >> 1;
451*08b48e0bSAndroid Build Coastguard Worker 
452*08b48e0bSAndroid Build Coastguard Worker     for (j = 0; j < afl->extras[i].len; ++j) {
453*08b48e0bSAndroid Build Coastguard Worker 
454*08b48e0bSAndroid Build Coastguard Worker       switch (j % 4) {
455*08b48e0bSAndroid Build Coastguard Worker 
456*08b48e0bSAndroid Build Coastguard Worker         case 2:
457*08b48e0bSAndroid Build Coastguard Worker           if (!afl->extras[i].data[j]) { ++z3; }
458*08b48e0bSAndroid Build Coastguard Worker           // fall through
459*08b48e0bSAndroid Build Coastguard Worker         case 0:
460*08b48e0bSAndroid Build Coastguard Worker           if (!afl->extras[i].data[j]) { ++z1; }
461*08b48e0bSAndroid Build Coastguard Worker           break;
462*08b48e0bSAndroid Build Coastguard Worker         case 3:
463*08b48e0bSAndroid Build Coastguard Worker           if (!afl->extras[i].data[j]) { ++z4; }
464*08b48e0bSAndroid Build Coastguard Worker           // fall through
465*08b48e0bSAndroid Build Coastguard Worker         case 1:
466*08b48e0bSAndroid Build Coastguard Worker           if (!afl->extras[i].data[j]) { ++z2; }
467*08b48e0bSAndroid Build Coastguard Worker           break;
468*08b48e0bSAndroid Build Coastguard Worker 
469*08b48e0bSAndroid Build Coastguard Worker       }
470*08b48e0bSAndroid Build Coastguard Worker 
471*08b48e0bSAndroid Build Coastguard Worker     }
472*08b48e0bSAndroid Build Coastguard Worker 
473*08b48e0bSAndroid Build Coastguard Worker     if ((z1 < half && z2 < half) || z1 + z2 == afl->extras[i].len) { continue; }
474*08b48e0bSAndroid Build Coastguard Worker 
475*08b48e0bSAndroid Build Coastguard Worker     // also maybe 32 bit unicode?
476*08b48e0bSAndroid Build Coastguard Worker     if (afl->extras[i].len % 4 == 0 && afl->extras[i].len >= 12 &&
477*08b48e0bSAndroid Build Coastguard Worker         (z3 == quarter || z4 == quarter) && z1 + z2 == quarter * 3) {
478*08b48e0bSAndroid Build Coastguard Worker 
479*08b48e0bSAndroid Build Coastguard Worker       for (j = 0; j < afl->extras[i].len; ++j) {
480*08b48e0bSAndroid Build Coastguard Worker 
481*08b48e0bSAndroid Build Coastguard Worker         if (z4 < quarter) {
482*08b48e0bSAndroid Build Coastguard Worker 
483*08b48e0bSAndroid Build Coastguard Worker           if (j % 4 == 3) { buf[k++] = afl->extras[i].data[j]; }
484*08b48e0bSAndroid Build Coastguard Worker 
485*08b48e0bSAndroid Build Coastguard Worker         } else if (z3 < quarter) {
486*08b48e0bSAndroid Build Coastguard Worker 
487*08b48e0bSAndroid Build Coastguard Worker           if (j % 4 == 2) { buf[k++] = afl->extras[i].data[j]; }
488*08b48e0bSAndroid Build Coastguard Worker 
489*08b48e0bSAndroid Build Coastguard Worker         } else if (z2 < half) {
490*08b48e0bSAndroid Build Coastguard Worker 
491*08b48e0bSAndroid Build Coastguard Worker           if (j % 4 == 1) { buf[k++] = afl->extras[i].data[j]; }
492*08b48e0bSAndroid Build Coastguard Worker 
493*08b48e0bSAndroid Build Coastguard Worker         } else {
494*08b48e0bSAndroid Build Coastguard Worker 
495*08b48e0bSAndroid Build Coastguard Worker           if (j % 4 == 0) { buf[k++] = afl->extras[i].data[j]; }
496*08b48e0bSAndroid Build Coastguard Worker 
497*08b48e0bSAndroid Build Coastguard Worker         }
498*08b48e0bSAndroid Build Coastguard Worker 
499*08b48e0bSAndroid Build Coastguard Worker       }
500*08b48e0bSAndroid Build Coastguard Worker 
501*08b48e0bSAndroid Build Coastguard Worker       add_extra_nocheck(afl, buf, k);
502*08b48e0bSAndroid Build Coastguard Worker       k = 0;
503*08b48e0bSAndroid Build Coastguard Worker 
504*08b48e0bSAndroid Build Coastguard Worker     }
505*08b48e0bSAndroid Build Coastguard Worker 
506*08b48e0bSAndroid Build Coastguard Worker     for (j = 0; j < afl->extras[i].len; ++j) {
507*08b48e0bSAndroid Build Coastguard Worker 
508*08b48e0bSAndroid Build Coastguard Worker       if (z1 < half) {
509*08b48e0bSAndroid Build Coastguard Worker 
510*08b48e0bSAndroid Build Coastguard Worker         if (j % 2 == 0) { buf[k++] = afl->extras[i].data[j]; }
511*08b48e0bSAndroid Build Coastguard Worker 
512*08b48e0bSAndroid Build Coastguard Worker       } else {
513*08b48e0bSAndroid Build Coastguard Worker 
514*08b48e0bSAndroid Build Coastguard Worker         if (j % 2 == 1) { buf[k++] = afl->extras[i].data[j]; }
515*08b48e0bSAndroid Build Coastguard Worker 
516*08b48e0bSAndroid Build Coastguard Worker       }
517*08b48e0bSAndroid Build Coastguard Worker 
518*08b48e0bSAndroid Build Coastguard Worker     }
519*08b48e0bSAndroid Build Coastguard Worker 
520*08b48e0bSAndroid Build Coastguard Worker     add_extra_nocheck(afl, buf, k);
521*08b48e0bSAndroid Build Coastguard Worker 
522*08b48e0bSAndroid Build Coastguard Worker   }
523*08b48e0bSAndroid Build Coastguard Worker 
524*08b48e0bSAndroid Build Coastguard Worker   qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
525*08b48e0bSAndroid Build Coastguard Worker         compare_extras_len);
526*08b48e0bSAndroid Build Coastguard Worker 
527*08b48e0bSAndroid Build Coastguard Worker }
528*08b48e0bSAndroid Build Coastguard Worker 
529*08b48e0bSAndroid Build Coastguard Worker /* Removes duplicates from the loaded extras. This can happen if multiple files
530*08b48e0bSAndroid Build Coastguard Worker    are loaded */
531*08b48e0bSAndroid Build Coastguard Worker 
dedup_extras(afl_state_t * afl)532*08b48e0bSAndroid Build Coastguard Worker void dedup_extras(afl_state_t *afl) {
533*08b48e0bSAndroid Build Coastguard Worker 
534*08b48e0bSAndroid Build Coastguard Worker   if (afl->extras_cnt < 2) return;
535*08b48e0bSAndroid Build Coastguard Worker 
536*08b48e0bSAndroid Build Coastguard Worker   u32 i, j, orig_cnt = afl->extras_cnt;
537*08b48e0bSAndroid Build Coastguard Worker 
538*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < afl->extras_cnt - 1; ++i) {
539*08b48e0bSAndroid Build Coastguard Worker 
540*08b48e0bSAndroid Build Coastguard Worker     for (j = i + 1; j < afl->extras_cnt; ++j) {
541*08b48e0bSAndroid Build Coastguard Worker 
542*08b48e0bSAndroid Build Coastguard Worker     restart_dedup:
543*08b48e0bSAndroid Build Coastguard Worker 
544*08b48e0bSAndroid Build Coastguard Worker       // if the goto was used we could be at the end of the list
545*08b48e0bSAndroid Build Coastguard Worker       if (j >= afl->extras_cnt || afl->extras[i].len != afl->extras[j].len)
546*08b48e0bSAndroid Build Coastguard Worker         break;
547*08b48e0bSAndroid Build Coastguard Worker 
548*08b48e0bSAndroid Build Coastguard Worker       if (memcmp(afl->extras[i].data, afl->extras[j].data,
549*08b48e0bSAndroid Build Coastguard Worker                  afl->extras[i].len) == 0) {
550*08b48e0bSAndroid Build Coastguard Worker 
551*08b48e0bSAndroid Build Coastguard Worker         ck_free(afl->extras[j].data);
552*08b48e0bSAndroid Build Coastguard Worker         if (j + 1 < afl->extras_cnt)  // not at the end of the list?
553*08b48e0bSAndroid Build Coastguard Worker           memmove((char *)&afl->extras[j], (char *)&afl->extras[j + 1],
554*08b48e0bSAndroid Build Coastguard Worker                   (afl->extras_cnt - j - 1) * sizeof(struct extra_data));
555*08b48e0bSAndroid Build Coastguard Worker         --afl->extras_cnt;
556*08b48e0bSAndroid Build Coastguard Worker         goto restart_dedup;  // restart if several duplicates are in a row
557*08b48e0bSAndroid Build Coastguard Worker 
558*08b48e0bSAndroid Build Coastguard Worker       }
559*08b48e0bSAndroid Build Coastguard Worker 
560*08b48e0bSAndroid Build Coastguard Worker     }
561*08b48e0bSAndroid Build Coastguard Worker 
562*08b48e0bSAndroid Build Coastguard Worker   }
563*08b48e0bSAndroid Build Coastguard Worker 
564*08b48e0bSAndroid Build Coastguard Worker   if (afl->extras_cnt != orig_cnt)
565*08b48e0bSAndroid Build Coastguard Worker     afl->extras = afl_realloc_exact(
566*08b48e0bSAndroid Build Coastguard Worker         (void **)&afl->extras, afl->extras_cnt * sizeof(struct extra_data));
567*08b48e0bSAndroid Build Coastguard Worker 
568*08b48e0bSAndroid Build Coastguard Worker }
569*08b48e0bSAndroid Build Coastguard Worker 
570*08b48e0bSAndroid Build Coastguard Worker /* Adds a new extra / dict entry. */
add_extra(afl_state_t * afl,u8 * mem,u32 len)571*08b48e0bSAndroid Build Coastguard Worker void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
572*08b48e0bSAndroid Build Coastguard Worker 
573*08b48e0bSAndroid Build Coastguard Worker   u32 i, found = 0;
574*08b48e0bSAndroid Build Coastguard Worker 
575*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < afl->extras_cnt; i++) {
576*08b48e0bSAndroid Build Coastguard Worker 
577*08b48e0bSAndroid Build Coastguard Worker     if (afl->extras[i].len == len) {
578*08b48e0bSAndroid Build Coastguard Worker 
579*08b48e0bSAndroid Build Coastguard Worker       if (memcmp(afl->extras[i].data, mem, len) == 0) return;
580*08b48e0bSAndroid Build Coastguard Worker       found = 1;
581*08b48e0bSAndroid Build Coastguard Worker 
582*08b48e0bSAndroid Build Coastguard Worker     } else {
583*08b48e0bSAndroid Build Coastguard Worker 
584*08b48e0bSAndroid Build Coastguard Worker       if (found) break;
585*08b48e0bSAndroid Build Coastguard Worker 
586*08b48e0bSAndroid Build Coastguard Worker     }
587*08b48e0bSAndroid Build Coastguard Worker 
588*08b48e0bSAndroid Build Coastguard Worker   }
589*08b48e0bSAndroid Build Coastguard Worker 
590*08b48e0bSAndroid Build Coastguard Worker   if (len > MAX_DICT_FILE) {
591*08b48e0bSAndroid Build Coastguard Worker 
592*08b48e0bSAndroid Build Coastguard Worker     u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
593*08b48e0bSAndroid Build Coastguard Worker     WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len,
594*08b48e0bSAndroid Build Coastguard Worker           mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
595*08b48e0bSAndroid Build Coastguard Worker           stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
596*08b48e0bSAndroid Build Coastguard Worker     return;
597*08b48e0bSAndroid Build Coastguard Worker 
598*08b48e0bSAndroid Build Coastguard Worker   } else if (len > 32) {
599*08b48e0bSAndroid Build Coastguard Worker 
600*08b48e0bSAndroid Build Coastguard Worker     WARNF("Extra '%.*s' is pretty large, consider trimming.", (int)len, mem);
601*08b48e0bSAndroid Build Coastguard Worker 
602*08b48e0bSAndroid Build Coastguard Worker   }
603*08b48e0bSAndroid Build Coastguard Worker 
604*08b48e0bSAndroid Build Coastguard Worker   add_extra_nocheck(afl, mem, len);
605*08b48e0bSAndroid Build Coastguard Worker 
606*08b48e0bSAndroid Build Coastguard Worker   qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
607*08b48e0bSAndroid Build Coastguard Worker         compare_extras_len);
608*08b48e0bSAndroid Build Coastguard Worker 
609*08b48e0bSAndroid Build Coastguard Worker }
610*08b48e0bSAndroid Build Coastguard Worker 
611*08b48e0bSAndroid Build Coastguard Worker /* Maybe add automatic extra. */
612*08b48e0bSAndroid Build Coastguard Worker 
maybe_add_auto(afl_state_t * afl,u8 * mem,u32 len)613*08b48e0bSAndroid Build Coastguard Worker void maybe_add_auto(afl_state_t *afl, u8 *mem, u32 len) {
614*08b48e0bSAndroid Build Coastguard Worker 
615*08b48e0bSAndroid Build Coastguard Worker   u32 i;
616*08b48e0bSAndroid Build Coastguard Worker 
617*08b48e0bSAndroid Build Coastguard Worker   /* Allow users to specify that they don't want auto dictionaries. */
618*08b48e0bSAndroid Build Coastguard Worker 
619*08b48e0bSAndroid Build Coastguard Worker   if (!MAX_AUTO_EXTRAS || !USE_AUTO_EXTRAS) { return; }
620*08b48e0bSAndroid Build Coastguard Worker 
621*08b48e0bSAndroid Build Coastguard Worker   /* Skip runs of identical bytes. */
622*08b48e0bSAndroid Build Coastguard Worker 
623*08b48e0bSAndroid Build Coastguard Worker   for (i = 1; i < len; ++i) {
624*08b48e0bSAndroid Build Coastguard Worker 
625*08b48e0bSAndroid Build Coastguard Worker     if (mem[0] ^ mem[i]) { break; }
626*08b48e0bSAndroid Build Coastguard Worker 
627*08b48e0bSAndroid Build Coastguard Worker   }
628*08b48e0bSAndroid Build Coastguard Worker 
629*08b48e0bSAndroid Build Coastguard Worker   if (i == len || unlikely(len > MAX_AUTO_EXTRA)) { return; }
630*08b48e0bSAndroid Build Coastguard Worker 
631*08b48e0bSAndroid Build Coastguard Worker   /* Reject builtin interesting values. */
632*08b48e0bSAndroid Build Coastguard Worker 
633*08b48e0bSAndroid Build Coastguard Worker   if (len == 2) {
634*08b48e0bSAndroid Build Coastguard Worker 
635*08b48e0bSAndroid Build Coastguard Worker     i = sizeof(interesting_16) >> 1;
636*08b48e0bSAndroid Build Coastguard Worker 
637*08b48e0bSAndroid Build Coastguard Worker     while (i--) {
638*08b48e0bSAndroid Build Coastguard Worker 
639*08b48e0bSAndroid Build Coastguard Worker       if (*((u16 *)mem) == interesting_16[i] ||
640*08b48e0bSAndroid Build Coastguard Worker           *((u16 *)mem) == SWAP16(interesting_16[i])) {
641*08b48e0bSAndroid Build Coastguard Worker 
642*08b48e0bSAndroid Build Coastguard Worker         return;
643*08b48e0bSAndroid Build Coastguard Worker 
644*08b48e0bSAndroid Build Coastguard Worker       }
645*08b48e0bSAndroid Build Coastguard Worker 
646*08b48e0bSAndroid Build Coastguard Worker     }
647*08b48e0bSAndroid Build Coastguard Worker 
648*08b48e0bSAndroid Build Coastguard Worker   }
649*08b48e0bSAndroid Build Coastguard Worker 
650*08b48e0bSAndroid Build Coastguard Worker   if (len == 4) {
651*08b48e0bSAndroid Build Coastguard Worker 
652*08b48e0bSAndroid Build Coastguard Worker     i = sizeof(interesting_32) >> 2;
653*08b48e0bSAndroid Build Coastguard Worker 
654*08b48e0bSAndroid Build Coastguard Worker     while (i--) {
655*08b48e0bSAndroid Build Coastguard Worker 
656*08b48e0bSAndroid Build Coastguard Worker       if (*((u32 *)mem) == (u32)interesting_32[i] ||
657*08b48e0bSAndroid Build Coastguard Worker           *((u32 *)mem) == SWAP32(interesting_32[i])) {
658*08b48e0bSAndroid Build Coastguard Worker 
659*08b48e0bSAndroid Build Coastguard Worker         return;
660*08b48e0bSAndroid Build Coastguard Worker 
661*08b48e0bSAndroid Build Coastguard Worker       }
662*08b48e0bSAndroid Build Coastguard Worker 
663*08b48e0bSAndroid Build Coastguard Worker     }
664*08b48e0bSAndroid Build Coastguard Worker 
665*08b48e0bSAndroid Build Coastguard Worker   }
666*08b48e0bSAndroid Build Coastguard Worker 
667*08b48e0bSAndroid Build Coastguard Worker   /* Reject anything that matches existing extras. Do a case-insensitive
668*08b48e0bSAndroid Build Coastguard Worker      match. We optimize by exploiting the fact that extras[] are sorted
669*08b48e0bSAndroid Build Coastguard Worker      by size. */
670*08b48e0bSAndroid Build Coastguard Worker 
671*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < afl->extras_cnt; ++i) {
672*08b48e0bSAndroid Build Coastguard Worker 
673*08b48e0bSAndroid Build Coastguard Worker     if (afl->extras[i].len >= len) { break; }
674*08b48e0bSAndroid Build Coastguard Worker 
675*08b48e0bSAndroid Build Coastguard Worker   }
676*08b48e0bSAndroid Build Coastguard Worker 
677*08b48e0bSAndroid Build Coastguard Worker   for (; i < afl->extras_cnt && afl->extras[i].len == len; ++i) {
678*08b48e0bSAndroid Build Coastguard Worker 
679*08b48e0bSAndroid Build Coastguard Worker     if (!memcmp_nocase(afl->extras[i].data, mem, len)) { return; }
680*08b48e0bSAndroid Build Coastguard Worker 
681*08b48e0bSAndroid Build Coastguard Worker   }
682*08b48e0bSAndroid Build Coastguard Worker 
683*08b48e0bSAndroid Build Coastguard Worker   /* Last but not least, check afl->a_extras[] for matches. There are no
684*08b48e0bSAndroid Build Coastguard Worker      guarantees of a particular sort order. */
685*08b48e0bSAndroid Build Coastguard Worker 
686*08b48e0bSAndroid Build Coastguard Worker   afl->auto_changed = 1;
687*08b48e0bSAndroid Build Coastguard Worker 
688*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < afl->a_extras_cnt; ++i) {
689*08b48e0bSAndroid Build Coastguard Worker 
690*08b48e0bSAndroid Build Coastguard Worker     if (afl->a_extras[i].len == len &&
691*08b48e0bSAndroid Build Coastguard Worker         !memcmp_nocase(afl->a_extras[i].data, mem, len)) {
692*08b48e0bSAndroid Build Coastguard Worker 
693*08b48e0bSAndroid Build Coastguard Worker       afl->a_extras[i].hit_cnt++;
694*08b48e0bSAndroid Build Coastguard Worker       goto sort_a_extras;
695*08b48e0bSAndroid Build Coastguard Worker 
696*08b48e0bSAndroid Build Coastguard Worker     }
697*08b48e0bSAndroid Build Coastguard Worker 
698*08b48e0bSAndroid Build Coastguard Worker   }
699*08b48e0bSAndroid Build Coastguard Worker 
700*08b48e0bSAndroid Build Coastguard Worker   /* At this point, looks like we're dealing with a new entry. So, let's
701*08b48e0bSAndroid Build Coastguard Worker      append it if we have room. Otherwise, let's randomly evict some other
702*08b48e0bSAndroid Build Coastguard Worker      entry from the bottom half of the list. */
703*08b48e0bSAndroid Build Coastguard Worker 
704*08b48e0bSAndroid Build Coastguard Worker   if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) {
705*08b48e0bSAndroid Build Coastguard Worker 
706*08b48e0bSAndroid Build Coastguard Worker     memcpy(afl->a_extras[afl->a_extras_cnt].data, mem, len);
707*08b48e0bSAndroid Build Coastguard Worker     afl->a_extras[afl->a_extras_cnt].len = len;
708*08b48e0bSAndroid Build Coastguard Worker     ++afl->a_extras_cnt;
709*08b48e0bSAndroid Build Coastguard Worker 
710*08b48e0bSAndroid Build Coastguard Worker   } else {
711*08b48e0bSAndroid Build Coastguard Worker 
712*08b48e0bSAndroid Build Coastguard Worker     i = MAX_AUTO_EXTRAS / 2 + rand_below(afl, (MAX_AUTO_EXTRAS + 1) / 2);
713*08b48e0bSAndroid Build Coastguard Worker 
714*08b48e0bSAndroid Build Coastguard Worker     memcpy(afl->a_extras[i].data, mem, len);
715*08b48e0bSAndroid Build Coastguard Worker     afl->a_extras[i].len = len;
716*08b48e0bSAndroid Build Coastguard Worker     afl->a_extras[i].hit_cnt = 0;
717*08b48e0bSAndroid Build Coastguard Worker 
718*08b48e0bSAndroid Build Coastguard Worker   }
719*08b48e0bSAndroid Build Coastguard Worker 
720*08b48e0bSAndroid Build Coastguard Worker sort_a_extras:
721*08b48e0bSAndroid Build Coastguard Worker 
722*08b48e0bSAndroid Build Coastguard Worker   /* First, sort all auto extras by use count, descending order. */
723*08b48e0bSAndroid Build Coastguard Worker 
724*08b48e0bSAndroid Build Coastguard Worker   qsort(afl->a_extras, afl->a_extras_cnt, sizeof(struct auto_extra_data),
725*08b48e0bSAndroid Build Coastguard Worker         compare_auto_extras_use_d);
726*08b48e0bSAndroid Build Coastguard Worker 
727*08b48e0bSAndroid Build Coastguard Worker   /* Then, sort the top USE_AUTO_EXTRAS entries by size. */
728*08b48e0bSAndroid Build Coastguard Worker 
729*08b48e0bSAndroid Build Coastguard Worker   qsort(afl->a_extras, MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt),
730*08b48e0bSAndroid Build Coastguard Worker         sizeof(struct auto_extra_data), compare_auto_extras_len);
731*08b48e0bSAndroid Build Coastguard Worker 
732*08b48e0bSAndroid Build Coastguard Worker }
733*08b48e0bSAndroid Build Coastguard Worker 
734*08b48e0bSAndroid Build Coastguard Worker /* Save automatically generated extras. */
735*08b48e0bSAndroid Build Coastguard Worker 
save_auto(afl_state_t * afl)736*08b48e0bSAndroid Build Coastguard Worker void save_auto(afl_state_t *afl) {
737*08b48e0bSAndroid Build Coastguard Worker 
738*08b48e0bSAndroid Build Coastguard Worker   u32 i;
739*08b48e0bSAndroid Build Coastguard Worker 
740*08b48e0bSAndroid Build Coastguard Worker   if (!afl->auto_changed) { return; }
741*08b48e0bSAndroid Build Coastguard Worker   afl->auto_changed = 0;
742*08b48e0bSAndroid Build Coastguard Worker 
743*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
744*08b48e0bSAndroid Build Coastguard Worker 
745*08b48e0bSAndroid Build Coastguard Worker     u8 *fn =
746*08b48e0bSAndroid Build Coastguard Worker         alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
747*08b48e0bSAndroid Build Coastguard Worker     s32 fd;
748*08b48e0bSAndroid Build Coastguard Worker 
749*08b48e0bSAndroid Build Coastguard Worker     fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
750*08b48e0bSAndroid Build Coastguard Worker 
751*08b48e0bSAndroid Build Coastguard Worker     if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
752*08b48e0bSAndroid Build Coastguard Worker 
753*08b48e0bSAndroid Build Coastguard Worker     ck_write(fd, afl->a_extras[i].data, afl->a_extras[i].len, fn);
754*08b48e0bSAndroid Build Coastguard Worker 
755*08b48e0bSAndroid Build Coastguard Worker     close(fd);
756*08b48e0bSAndroid Build Coastguard Worker     ck_free(fn);
757*08b48e0bSAndroid Build Coastguard Worker 
758*08b48e0bSAndroid Build Coastguard Worker   }
759*08b48e0bSAndroid Build Coastguard Worker 
760*08b48e0bSAndroid Build Coastguard Worker }
761*08b48e0bSAndroid Build Coastguard Worker 
762*08b48e0bSAndroid Build Coastguard Worker /* Load automatically generated extras. */
763*08b48e0bSAndroid Build Coastguard Worker 
load_auto(afl_state_t * afl)764*08b48e0bSAndroid Build Coastguard Worker void load_auto(afl_state_t *afl) {
765*08b48e0bSAndroid Build Coastguard Worker 
766*08b48e0bSAndroid Build Coastguard Worker   u32 i;
767*08b48e0bSAndroid Build Coastguard Worker 
768*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < USE_AUTO_EXTRAS; ++i) {
769*08b48e0bSAndroid Build Coastguard Worker 
770*08b48e0bSAndroid Build Coastguard Worker     u8  tmp[MAX_AUTO_EXTRA + 1];
771*08b48e0bSAndroid Build Coastguard Worker     u8 *fn = alloc_printf("%s/.state/auto_extras/auto_%06u", afl->in_dir, i);
772*08b48e0bSAndroid Build Coastguard Worker     s32 fd, len;
773*08b48e0bSAndroid Build Coastguard Worker 
774*08b48e0bSAndroid Build Coastguard Worker     fd = open(fn, O_RDONLY);
775*08b48e0bSAndroid Build Coastguard Worker 
776*08b48e0bSAndroid Build Coastguard Worker     if (fd < 0) {
777*08b48e0bSAndroid Build Coastguard Worker 
778*08b48e0bSAndroid Build Coastguard Worker       if (errno != ENOENT) { PFATAL("Unable to open '%s'", fn); }
779*08b48e0bSAndroid Build Coastguard Worker       ck_free(fn);
780*08b48e0bSAndroid Build Coastguard Worker       break;
781*08b48e0bSAndroid Build Coastguard Worker 
782*08b48e0bSAndroid Build Coastguard Worker     }
783*08b48e0bSAndroid Build Coastguard Worker 
784*08b48e0bSAndroid Build Coastguard Worker     /* We read one byte more to cheaply detect tokens that are too
785*08b48e0bSAndroid Build Coastguard Worker        long (and skip them). */
786*08b48e0bSAndroid Build Coastguard Worker 
787*08b48e0bSAndroid Build Coastguard Worker     len = read(fd, tmp, MAX_AUTO_EXTRA + 1);
788*08b48e0bSAndroid Build Coastguard Worker 
789*08b48e0bSAndroid Build Coastguard Worker     if (len < 0) { PFATAL("Unable to read from '%s'", fn); }
790*08b48e0bSAndroid Build Coastguard Worker 
791*08b48e0bSAndroid Build Coastguard Worker     if (len >= MIN_AUTO_EXTRA && len <= MAX_AUTO_EXTRA) {
792*08b48e0bSAndroid Build Coastguard Worker 
793*08b48e0bSAndroid Build Coastguard Worker       maybe_add_auto(afl, tmp, len);
794*08b48e0bSAndroid Build Coastguard Worker 
795*08b48e0bSAndroid Build Coastguard Worker     }
796*08b48e0bSAndroid Build Coastguard Worker 
797*08b48e0bSAndroid Build Coastguard Worker     close(fd);
798*08b48e0bSAndroid Build Coastguard Worker     ck_free(fn);
799*08b48e0bSAndroid Build Coastguard Worker 
800*08b48e0bSAndroid Build Coastguard Worker   }
801*08b48e0bSAndroid Build Coastguard Worker 
802*08b48e0bSAndroid Build Coastguard Worker   if (i) {
803*08b48e0bSAndroid Build Coastguard Worker 
804*08b48e0bSAndroid Build Coastguard Worker     OKF("Loaded %u auto-discovered dictionary tokens.", i);
805*08b48e0bSAndroid Build Coastguard Worker 
806*08b48e0bSAndroid Build Coastguard Worker   } else {
807*08b48e0bSAndroid Build Coastguard Worker 
808*08b48e0bSAndroid Build Coastguard Worker     ACTF("No auto-generated dictionary tokens to reuse.");
809*08b48e0bSAndroid Build Coastguard Worker 
810*08b48e0bSAndroid Build Coastguard Worker   }
811*08b48e0bSAndroid Build Coastguard Worker 
812*08b48e0bSAndroid Build Coastguard Worker }
813*08b48e0bSAndroid Build Coastguard Worker 
814*08b48e0bSAndroid Build Coastguard Worker /* Destroy extras. */
815*08b48e0bSAndroid Build Coastguard Worker 
destroy_extras(afl_state_t * afl)816*08b48e0bSAndroid Build Coastguard Worker void destroy_extras(afl_state_t *afl) {
817*08b48e0bSAndroid Build Coastguard Worker 
818*08b48e0bSAndroid Build Coastguard Worker   u32 i;
819*08b48e0bSAndroid Build Coastguard Worker 
820*08b48e0bSAndroid Build Coastguard Worker   for (i = 0; i < afl->extras_cnt; ++i) {
821*08b48e0bSAndroid Build Coastguard Worker 
822*08b48e0bSAndroid Build Coastguard Worker     ck_free(afl->extras[i].data);
823*08b48e0bSAndroid Build Coastguard Worker 
824*08b48e0bSAndroid Build Coastguard Worker   }
825*08b48e0bSAndroid Build Coastguard Worker 
826*08b48e0bSAndroid Build Coastguard Worker   afl_free(afl->extras);
827*08b48e0bSAndroid Build Coastguard Worker 
828*08b48e0bSAndroid Build Coastguard Worker }
829*08b48e0bSAndroid Build Coastguard Worker 
830