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