1*08b48e0bSAndroid Build Coastguard Worker
2*08b48e0bSAndroid Build Coastguard Worker
3*08b48e0bSAndroid Build Coastguard Worker #include "afl-fuzz.h"
4*08b48e0bSAndroid Build Coastguard Worker
flip_range(u8 * input,u32 pos,u32 size)5*08b48e0bSAndroid Build Coastguard Worker void flip_range(u8 *input, u32 pos, u32 size) {
6*08b48e0bSAndroid Build Coastguard Worker
7*08b48e0bSAndroid Build Coastguard Worker for (u32 i = 0; i < size; i++)
8*08b48e0bSAndroid Build Coastguard Worker input[pos + i] ^= 0xFF;
9*08b48e0bSAndroid Build Coastguard Worker
10*08b48e0bSAndroid Build Coastguard Worker return;
11*08b48e0bSAndroid Build Coastguard Worker
12*08b48e0bSAndroid Build Coastguard Worker }
13*08b48e0bSAndroid Build Coastguard Worker
14*08b48e0bSAndroid Build Coastguard Worker #define MAX_EFF_TIMEOUT (10 * 60 * 1000)
15*08b48e0bSAndroid Build Coastguard Worker #define MAX_DET_TIMEOUT (15 * 60 * 1000)
is_det_timeout(u64 cur_ms,u8 is_flip)16*08b48e0bSAndroid Build Coastguard Worker u8 is_det_timeout(u64 cur_ms, u8 is_flip) {
17*08b48e0bSAndroid Build Coastguard Worker
18*08b48e0bSAndroid Build Coastguard Worker if (is_flip) {
19*08b48e0bSAndroid Build Coastguard Worker
20*08b48e0bSAndroid Build Coastguard Worker if (unlikely(get_cur_time() - cur_ms > MAX_EFF_TIMEOUT)) return 1;
21*08b48e0bSAndroid Build Coastguard Worker
22*08b48e0bSAndroid Build Coastguard Worker } else {
23*08b48e0bSAndroid Build Coastguard Worker
24*08b48e0bSAndroid Build Coastguard Worker if (unlikely(get_cur_time() - cur_ms > MAX_DET_TIMEOUT)) return 1;
25*08b48e0bSAndroid Build Coastguard Worker
26*08b48e0bSAndroid Build Coastguard Worker }
27*08b48e0bSAndroid Build Coastguard Worker
28*08b48e0bSAndroid Build Coastguard Worker return 0;
29*08b48e0bSAndroid Build Coastguard Worker
30*08b48e0bSAndroid Build Coastguard Worker }
31*08b48e0bSAndroid Build Coastguard Worker
32*08b48e0bSAndroid Build Coastguard Worker /* decide if the seed should be deterministically fuzzed */
33*08b48e0bSAndroid Build Coastguard Worker
should_det_fuzz(afl_state_t * afl,struct queue_entry * q)34*08b48e0bSAndroid Build Coastguard Worker u8 should_det_fuzz(afl_state_t *afl, struct queue_entry *q) {
35*08b48e0bSAndroid Build Coastguard Worker
36*08b48e0bSAndroid Build Coastguard Worker if (!afl->skipdet_g->virgin_det_bits) {
37*08b48e0bSAndroid Build Coastguard Worker
38*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->virgin_det_bits =
39*08b48e0bSAndroid Build Coastguard Worker (u8 *)ck_alloc(sizeof(u8) * afl->fsrv.map_size);
40*08b48e0bSAndroid Build Coastguard Worker
41*08b48e0bSAndroid Build Coastguard Worker }
42*08b48e0bSAndroid Build Coastguard Worker
43*08b48e0bSAndroid Build Coastguard Worker if (!q->favored || q->passed_det) return 0;
44*08b48e0bSAndroid Build Coastguard Worker if (!q->trace_mini) return 0;
45*08b48e0bSAndroid Build Coastguard Worker
46*08b48e0bSAndroid Build Coastguard Worker if (!afl->skipdet_g->last_cov_undet)
47*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->last_cov_undet = get_cur_time();
48*08b48e0bSAndroid Build Coastguard Worker
49*08b48e0bSAndroid Build Coastguard Worker if (get_cur_time() - afl->skipdet_g->last_cov_undet >= THRESHOLD_DEC_TIME) {
50*08b48e0bSAndroid Build Coastguard Worker
51*08b48e0bSAndroid Build Coastguard Worker if (afl->skipdet_g->undet_bits_threshold >= 2) {
52*08b48e0bSAndroid Build Coastguard Worker
53*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->undet_bits_threshold *= 0.75;
54*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->last_cov_undet = get_cur_time();
55*08b48e0bSAndroid Build Coastguard Worker
56*08b48e0bSAndroid Build Coastguard Worker }
57*08b48e0bSAndroid Build Coastguard Worker
58*08b48e0bSAndroid Build Coastguard Worker }
59*08b48e0bSAndroid Build Coastguard Worker
60*08b48e0bSAndroid Build Coastguard Worker u32 new_det_bits = 0;
61*08b48e0bSAndroid Build Coastguard Worker
62*08b48e0bSAndroid Build Coastguard Worker for (u32 i = 0; i < afl->fsrv.map_size; i++) {
63*08b48e0bSAndroid Build Coastguard Worker
64*08b48e0bSAndroid Build Coastguard Worker if (unlikely(q->trace_mini[i >> 3] & (1 << (i & 7)))) {
65*08b48e0bSAndroid Build Coastguard Worker
66*08b48e0bSAndroid Build Coastguard Worker if (!afl->skipdet_g->virgin_det_bits[i]) { new_det_bits++; }
67*08b48e0bSAndroid Build Coastguard Worker
68*08b48e0bSAndroid Build Coastguard Worker }
69*08b48e0bSAndroid Build Coastguard Worker
70*08b48e0bSAndroid Build Coastguard Worker }
71*08b48e0bSAndroid Build Coastguard Worker
72*08b48e0bSAndroid Build Coastguard Worker if (!afl->skipdet_g->undet_bits_threshold)
73*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->undet_bits_threshold = new_det_bits * 0.05;
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker if (new_det_bits >= afl->skipdet_g->undet_bits_threshold) {
76*08b48e0bSAndroid Build Coastguard Worker
77*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->last_cov_undet = get_cur_time();
78*08b48e0bSAndroid Build Coastguard Worker q->skipdet_e->undet_bits = new_det_bits;
79*08b48e0bSAndroid Build Coastguard Worker
80*08b48e0bSAndroid Build Coastguard Worker for (u32 i = 0; i < afl->fsrv.map_size; i++) {
81*08b48e0bSAndroid Build Coastguard Worker
82*08b48e0bSAndroid Build Coastguard Worker if (unlikely(q->trace_mini[i >> 3] & (1 << (i & 7)))) {
83*08b48e0bSAndroid Build Coastguard Worker
84*08b48e0bSAndroid Build Coastguard Worker if (!afl->skipdet_g->virgin_det_bits[i])
85*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->virgin_det_bits[i] = 1;
86*08b48e0bSAndroid Build Coastguard Worker
87*08b48e0bSAndroid Build Coastguard Worker }
88*08b48e0bSAndroid Build Coastguard Worker
89*08b48e0bSAndroid Build Coastguard Worker }
90*08b48e0bSAndroid Build Coastguard Worker
91*08b48e0bSAndroid Build Coastguard Worker return 1;
92*08b48e0bSAndroid Build Coastguard Worker
93*08b48e0bSAndroid Build Coastguard Worker }
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker return 0;
96*08b48e0bSAndroid Build Coastguard Worker
97*08b48e0bSAndroid Build Coastguard Worker }
98*08b48e0bSAndroid Build Coastguard Worker
99*08b48e0bSAndroid Build Coastguard Worker /*
100*08b48e0bSAndroid Build Coastguard Worker consists of two stages that
101*08b48e0bSAndroid Build Coastguard Worker return 0 if exec failed.
102*08b48e0bSAndroid Build Coastguard Worker */
103*08b48e0bSAndroid Build Coastguard Worker
skip_deterministic_stage(afl_state_t * afl,u8 * orig_buf,u8 * out_buf,u32 len,u64 before_det_time)104*08b48e0bSAndroid Build Coastguard Worker u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
105*08b48e0bSAndroid Build Coastguard Worker u32 len, u64 before_det_time) {
106*08b48e0bSAndroid Build Coastguard Worker
107*08b48e0bSAndroid Build Coastguard Worker u64 orig_hit_cnt, new_hit_cnt;
108*08b48e0bSAndroid Build Coastguard Worker
109*08b48e0bSAndroid Build Coastguard Worker if (afl->queue_cur->skipdet_e->done_eff) return 1;
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker if (!should_det_fuzz(afl, afl->queue_cur)) return 1;
112*08b48e0bSAndroid Build Coastguard Worker
113*08b48e0bSAndroid Build Coastguard Worker /* Add check to make sure that for seeds without too much undet bits,
114*08b48e0bSAndroid Build Coastguard Worker we ignore them */
115*08b48e0bSAndroid Build Coastguard Worker
116*08b48e0bSAndroid Build Coastguard Worker /******************
117*08b48e0bSAndroid Build Coastguard Worker * SKIP INFERENCE *
118*08b48e0bSAndroid Build Coastguard Worker ******************/
119*08b48e0bSAndroid Build Coastguard Worker
120*08b48e0bSAndroid Build Coastguard Worker afl->stage_short = "inf";
121*08b48e0bSAndroid Build Coastguard Worker afl->stage_name = "inference";
122*08b48e0bSAndroid Build Coastguard Worker afl->stage_cur = 0;
123*08b48e0bSAndroid Build Coastguard Worker orig_hit_cnt = afl->queued_items + afl->saved_crashes;
124*08b48e0bSAndroid Build Coastguard Worker
125*08b48e0bSAndroid Build Coastguard Worker u8 *inf_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
126*08b48e0bSAndroid Build Coastguard Worker memset(inf_eff_map, 1, sizeof(u8) * len);
127*08b48e0bSAndroid Build Coastguard Worker
128*08b48e0bSAndroid Build Coastguard Worker if (common_fuzz_stuff(afl, orig_buf, len)) { return 0; }
129*08b48e0bSAndroid Build Coastguard Worker
130*08b48e0bSAndroid Build Coastguard Worker u64 prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
131*08b48e0bSAndroid Build Coastguard Worker u64 _prev_cksum = prev_cksum;
132*08b48e0bSAndroid Build Coastguard Worker
133*08b48e0bSAndroid Build Coastguard Worker if (MINIMAL_BLOCK_SIZE * 8 < len) {
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker // u64 size_skiped = 0, quick_skip_exec = total_execs, quick_skip_time =
136*08b48e0bSAndroid Build Coastguard Worker // get_cur_time();
137*08b48e0bSAndroid Build Coastguard Worker u64 pre_inf_exec = afl->fsrv.total_execs, pre_inf_time = get_cur_time();
138*08b48e0bSAndroid Build Coastguard Worker
139*08b48e0bSAndroid Build Coastguard Worker /* if determine stage time / input size is too small, just go ahead */
140*08b48e0bSAndroid Build Coastguard Worker
141*08b48e0bSAndroid Build Coastguard Worker u32 pos = 0, cur_block_size = MINIMAL_BLOCK_SIZE, max_block_size = len / 8;
142*08b48e0bSAndroid Build Coastguard Worker
143*08b48e0bSAndroid Build Coastguard Worker while (pos < len - 1) {
144*08b48e0bSAndroid Build Coastguard Worker
145*08b48e0bSAndroid Build Coastguard Worker cur_block_size = MINIMAL_BLOCK_SIZE;
146*08b48e0bSAndroid Build Coastguard Worker
147*08b48e0bSAndroid Build Coastguard Worker while (cur_block_size < max_block_size) {
148*08b48e0bSAndroid Build Coastguard Worker
149*08b48e0bSAndroid Build Coastguard Worker u32 flip_block_size =
150*08b48e0bSAndroid Build Coastguard Worker (cur_block_size + pos < len) ? cur_block_size : len - 1 - pos;
151*08b48e0bSAndroid Build Coastguard Worker
152*08b48e0bSAndroid Build Coastguard Worker afl->stage_cur += 1;
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker flip_range(out_buf, pos, flip_block_size);
155*08b48e0bSAndroid Build Coastguard Worker
156*08b48e0bSAndroid Build Coastguard Worker if (common_fuzz_stuff(afl, out_buf, len)) return 0;
157*08b48e0bSAndroid Build Coastguard Worker
158*08b48e0bSAndroid Build Coastguard Worker flip_range(out_buf, pos, flip_block_size);
159*08b48e0bSAndroid Build Coastguard Worker
160*08b48e0bSAndroid Build Coastguard Worker u64 cksum =
161*08b48e0bSAndroid Build Coastguard Worker hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
162*08b48e0bSAndroid Build Coastguard Worker
163*08b48e0bSAndroid Build Coastguard Worker // printf("Now trying range %d with %d, %s.\n", pos, cur_block_size,
164*08b48e0bSAndroid Build Coastguard Worker // (cksum == prev_cksum) ? (u8*)"Yes" : (u8*) "Not");
165*08b48e0bSAndroid Build Coastguard Worker
166*08b48e0bSAndroid Build Coastguard Worker /* continue until we fail or exceed length */
167*08b48e0bSAndroid Build Coastguard Worker if (cksum == _prev_cksum) {
168*08b48e0bSAndroid Build Coastguard Worker
169*08b48e0bSAndroid Build Coastguard Worker cur_block_size *= 2;
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker if (cur_block_size >= len - 1 - pos) break;
172*08b48e0bSAndroid Build Coastguard Worker
173*08b48e0bSAndroid Build Coastguard Worker } else {
174*08b48e0bSAndroid Build Coastguard Worker
175*08b48e0bSAndroid Build Coastguard Worker break;
176*08b48e0bSAndroid Build Coastguard Worker
177*08b48e0bSAndroid Build Coastguard Worker }
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker }
180*08b48e0bSAndroid Build Coastguard Worker
181*08b48e0bSAndroid Build Coastguard Worker if (cur_block_size == MINIMAL_BLOCK_SIZE) {
182*08b48e0bSAndroid Build Coastguard Worker
183*08b48e0bSAndroid Build Coastguard Worker /* we failed early on*/
184*08b48e0bSAndroid Build Coastguard Worker
185*08b48e0bSAndroid Build Coastguard Worker pos += cur_block_size;
186*08b48e0bSAndroid Build Coastguard Worker
187*08b48e0bSAndroid Build Coastguard Worker } else {
188*08b48e0bSAndroid Build Coastguard Worker
189*08b48e0bSAndroid Build Coastguard Worker u32 cur_skip_len = (cur_block_size / 2 + pos < len)
190*08b48e0bSAndroid Build Coastguard Worker ? (cur_block_size / 2)
191*08b48e0bSAndroid Build Coastguard Worker : (len - pos - 1);
192*08b48e0bSAndroid Build Coastguard Worker
193*08b48e0bSAndroid Build Coastguard Worker memset(inf_eff_map + pos, 0, cur_skip_len);
194*08b48e0bSAndroid Build Coastguard Worker
195*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->inf_prof->inf_skipped_bytes += cur_skip_len;
196*08b48e0bSAndroid Build Coastguard Worker
197*08b48e0bSAndroid Build Coastguard Worker pos += cur_skip_len;
198*08b48e0bSAndroid Build Coastguard Worker
199*08b48e0bSAndroid Build Coastguard Worker }
200*08b48e0bSAndroid Build Coastguard Worker
201*08b48e0bSAndroid Build Coastguard Worker }
202*08b48e0bSAndroid Build Coastguard Worker
203*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->inf_prof->inf_execs_cost +=
204*08b48e0bSAndroid Build Coastguard Worker (afl->fsrv.total_execs - pre_inf_exec);
205*08b48e0bSAndroid Build Coastguard Worker afl->skipdet_g->inf_prof->inf_time_cost += (get_cur_time() - pre_inf_time);
206*08b48e0bSAndroid Build Coastguard Worker // PFATAL("Done, now have %d bytes skipped, with exec %lld, time %lld.\n",
207*08b48e0bSAndroid Build Coastguard Worker // afl->inf_skipped_bytes, afl->inf_execs_cost, afl->inf_time_cost);
208*08b48e0bSAndroid Build Coastguard Worker
209*08b48e0bSAndroid Build Coastguard Worker } else
210*08b48e0bSAndroid Build Coastguard Worker
211*08b48e0bSAndroid Build Coastguard Worker memset(inf_eff_map, 1, len);
212*08b48e0bSAndroid Build Coastguard Worker
213*08b48e0bSAndroid Build Coastguard Worker new_hit_cnt = afl->queued_items + afl->saved_crashes;
214*08b48e0bSAndroid Build Coastguard Worker
215*08b48e0bSAndroid Build Coastguard Worker afl->stage_finds[STAGE_INF] += new_hit_cnt - orig_hit_cnt;
216*08b48e0bSAndroid Build Coastguard Worker afl->stage_cycles[STAGE_INF] += afl->stage_cur;
217*08b48e0bSAndroid Build Coastguard Worker
218*08b48e0bSAndroid Build Coastguard Worker /****************************
219*08b48e0bSAndroid Build Coastguard Worker * Quick Skip Effective Map *
220*08b48e0bSAndroid Build Coastguard Worker ****************************/
221*08b48e0bSAndroid Build Coastguard Worker
222*08b48e0bSAndroid Build Coastguard Worker /* Quick Effective Map Calculation */
223*08b48e0bSAndroid Build Coastguard Worker
224*08b48e0bSAndroid Build Coastguard Worker afl->stage_short = "quick";
225*08b48e0bSAndroid Build Coastguard Worker afl->stage_name = "quick eff";
226*08b48e0bSAndroid Build Coastguard Worker afl->stage_cur = 0;
227*08b48e0bSAndroid Build Coastguard Worker afl->stage_max = 32 * 1024;
228*08b48e0bSAndroid Build Coastguard Worker
229*08b48e0bSAndroid Build Coastguard Worker orig_hit_cnt = afl->queued_items + afl->saved_crashes;
230*08b48e0bSAndroid Build Coastguard Worker
231*08b48e0bSAndroid Build Coastguard Worker u32 before_skip_inf = afl->queued_items;
232*08b48e0bSAndroid Build Coastguard Worker
233*08b48e0bSAndroid Build Coastguard Worker /* clean all the eff bytes, since previous eff bytes are already fuzzed */
234*08b48e0bSAndroid Build Coastguard Worker u8 *skip_eff_map = afl->queue_cur->skipdet_e->skip_eff_map,
235*08b48e0bSAndroid Build Coastguard Worker *done_inf_map = afl->queue_cur->skipdet_e->done_inf_map;
236*08b48e0bSAndroid Build Coastguard Worker
237*08b48e0bSAndroid Build Coastguard Worker if (!skip_eff_map) {
238*08b48e0bSAndroid Build Coastguard Worker
239*08b48e0bSAndroid Build Coastguard Worker skip_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
240*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->skip_eff_map = skip_eff_map;
241*08b48e0bSAndroid Build Coastguard Worker
242*08b48e0bSAndroid Build Coastguard Worker } else {
243*08b48e0bSAndroid Build Coastguard Worker
244*08b48e0bSAndroid Build Coastguard Worker memset(skip_eff_map, 0, sizeof(u8) * len);
245*08b48e0bSAndroid Build Coastguard Worker
246*08b48e0bSAndroid Build Coastguard Worker }
247*08b48e0bSAndroid Build Coastguard Worker
248*08b48e0bSAndroid Build Coastguard Worker /* restore the starting point */
249*08b48e0bSAndroid Build Coastguard Worker if (!done_inf_map) {
250*08b48e0bSAndroid Build Coastguard Worker
251*08b48e0bSAndroid Build Coastguard Worker done_inf_map = (u8 *)ck_alloc(sizeof(u8) * len);
252*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->done_inf_map = done_inf_map;
253*08b48e0bSAndroid Build Coastguard Worker
254*08b48e0bSAndroid Build Coastguard Worker } else {
255*08b48e0bSAndroid Build Coastguard Worker
256*08b48e0bSAndroid Build Coastguard Worker for (afl->stage_cur = 0; afl->stage_cur < len; afl->stage_cur++) {
257*08b48e0bSAndroid Build Coastguard Worker
258*08b48e0bSAndroid Build Coastguard Worker if (done_inf_map[afl->stage_cur] == 0) break;
259*08b48e0bSAndroid Build Coastguard Worker
260*08b48e0bSAndroid Build Coastguard Worker }
261*08b48e0bSAndroid Build Coastguard Worker
262*08b48e0bSAndroid Build Coastguard Worker }
263*08b48e0bSAndroid Build Coastguard Worker
264*08b48e0bSAndroid Build Coastguard Worker /* depending on the seed's performance, we could search eff bytes
265*08b48e0bSAndroid Build Coastguard Worker for multiple rounds */
266*08b48e0bSAndroid Build Coastguard Worker
267*08b48e0bSAndroid Build Coastguard Worker u8 eff_round_continue = 1, eff_round_done = 0, done_eff = 0, repeat_eff = 0,
268*08b48e0bSAndroid Build Coastguard Worker fuzz_nearby = 0, *non_eff_bytes = 0;
269*08b48e0bSAndroid Build Coastguard Worker
270*08b48e0bSAndroid Build Coastguard Worker u64 before_eff_execs = afl->fsrv.total_execs;
271*08b48e0bSAndroid Build Coastguard Worker
272*08b48e0bSAndroid Build Coastguard Worker if (getenv("REPEAT_EFF")) repeat_eff = 1;
273*08b48e0bSAndroid Build Coastguard Worker if (getenv("FUZZ_NEARBY")) fuzz_nearby = 1;
274*08b48e0bSAndroid Build Coastguard Worker
275*08b48e0bSAndroid Build Coastguard Worker if (fuzz_nearby) {
276*08b48e0bSAndroid Build Coastguard Worker
277*08b48e0bSAndroid Build Coastguard Worker non_eff_bytes = (u8 *)ck_alloc(sizeof(u8) * len);
278*08b48e0bSAndroid Build Coastguard Worker
279*08b48e0bSAndroid Build Coastguard Worker // clean exec cksum
280*08b48e0bSAndroid Build Coastguard Worker if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
281*08b48e0bSAndroid Build Coastguard Worker prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
282*08b48e0bSAndroid Build Coastguard Worker
283*08b48e0bSAndroid Build Coastguard Worker }
284*08b48e0bSAndroid Build Coastguard Worker
285*08b48e0bSAndroid Build Coastguard Worker do {
286*08b48e0bSAndroid Build Coastguard Worker
287*08b48e0bSAndroid Build Coastguard Worker eff_round_continue = 0;
288*08b48e0bSAndroid Build Coastguard Worker afl->stage_max = 32 * 1024;
289*08b48e0bSAndroid Build Coastguard Worker
290*08b48e0bSAndroid Build Coastguard Worker for (; afl->stage_cur < afl->stage_max && afl->stage_cur < len;
291*08b48e0bSAndroid Build Coastguard Worker ++afl->stage_cur) {
292*08b48e0bSAndroid Build Coastguard Worker
293*08b48e0bSAndroid Build Coastguard Worker afl->stage_cur_byte = afl->stage_cur;
294*08b48e0bSAndroid Build Coastguard Worker
295*08b48e0bSAndroid Build Coastguard Worker if (!inf_eff_map[afl->stage_cur_byte] ||
296*08b48e0bSAndroid Build Coastguard Worker skip_eff_map[afl->stage_cur_byte])
297*08b48e0bSAndroid Build Coastguard Worker continue;
298*08b48e0bSAndroid Build Coastguard Worker
299*08b48e0bSAndroid Build Coastguard Worker if (is_det_timeout(before_det_time, 1)) { goto cleanup_skipdet; }
300*08b48e0bSAndroid Build Coastguard Worker
301*08b48e0bSAndroid Build Coastguard Worker u8 orig = out_buf[afl->stage_cur_byte], replace = rand_below(afl, 256);
302*08b48e0bSAndroid Build Coastguard Worker
303*08b48e0bSAndroid Build Coastguard Worker while (replace == orig) {
304*08b48e0bSAndroid Build Coastguard Worker
305*08b48e0bSAndroid Build Coastguard Worker replace = rand_below(afl, 256);
306*08b48e0bSAndroid Build Coastguard Worker
307*08b48e0bSAndroid Build Coastguard Worker }
308*08b48e0bSAndroid Build Coastguard Worker
309*08b48e0bSAndroid Build Coastguard Worker out_buf[afl->stage_cur_byte] = replace;
310*08b48e0bSAndroid Build Coastguard Worker
311*08b48e0bSAndroid Build Coastguard Worker before_skip_inf = afl->queued_items;
312*08b48e0bSAndroid Build Coastguard Worker
313*08b48e0bSAndroid Build Coastguard Worker if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
314*08b48e0bSAndroid Build Coastguard Worker
315*08b48e0bSAndroid Build Coastguard Worker out_buf[afl->stage_cur_byte] = orig;
316*08b48e0bSAndroid Build Coastguard Worker
317*08b48e0bSAndroid Build Coastguard Worker if (fuzz_nearby) {
318*08b48e0bSAndroid Build Coastguard Worker
319*08b48e0bSAndroid Build Coastguard Worker if (prev_cksum ==
320*08b48e0bSAndroid Build Coastguard Worker hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST)) {
321*08b48e0bSAndroid Build Coastguard Worker
322*08b48e0bSAndroid Build Coastguard Worker non_eff_bytes[afl->stage_cur_byte] = 1;
323*08b48e0bSAndroid Build Coastguard Worker
324*08b48e0bSAndroid Build Coastguard Worker }
325*08b48e0bSAndroid Build Coastguard Worker
326*08b48e0bSAndroid Build Coastguard Worker }
327*08b48e0bSAndroid Build Coastguard Worker
328*08b48e0bSAndroid Build Coastguard Worker if (afl->queued_items != before_skip_inf) {
329*08b48e0bSAndroid Build Coastguard Worker
330*08b48e0bSAndroid Build Coastguard Worker skip_eff_map[afl->stage_cur_byte] = 1;
331*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->quick_eff_bytes += 1;
332*08b48e0bSAndroid Build Coastguard Worker
333*08b48e0bSAndroid Build Coastguard Worker if (afl->stage_max < MAXIMUM_QUICK_EFF_EXECS) { afl->stage_max *= 2; }
334*08b48e0bSAndroid Build Coastguard Worker
335*08b48e0bSAndroid Build Coastguard Worker if (afl->stage_max == MAXIMUM_QUICK_EFF_EXECS && repeat_eff)
336*08b48e0bSAndroid Build Coastguard Worker eff_round_continue = 1;
337*08b48e0bSAndroid Build Coastguard Worker
338*08b48e0bSAndroid Build Coastguard Worker }
339*08b48e0bSAndroid Build Coastguard Worker
340*08b48e0bSAndroid Build Coastguard Worker done_inf_map[afl->stage_cur_byte] = 1;
341*08b48e0bSAndroid Build Coastguard Worker
342*08b48e0bSAndroid Build Coastguard Worker }
343*08b48e0bSAndroid Build Coastguard Worker
344*08b48e0bSAndroid Build Coastguard Worker afl->stage_cur = 0;
345*08b48e0bSAndroid Build Coastguard Worker done_eff = 1;
346*08b48e0bSAndroid Build Coastguard Worker
347*08b48e0bSAndroid Build Coastguard Worker if (++eff_round_done >= 8) break;
348*08b48e0bSAndroid Build Coastguard Worker
349*08b48e0bSAndroid Build Coastguard Worker } while (eff_round_continue);
350*08b48e0bSAndroid Build Coastguard Worker
351*08b48e0bSAndroid Build Coastguard Worker new_hit_cnt = afl->queued_items + afl->saved_crashes;
352*08b48e0bSAndroid Build Coastguard Worker
353*08b48e0bSAndroid Build Coastguard Worker afl->stage_finds[STAGE_QUICK] += new_hit_cnt - orig_hit_cnt;
354*08b48e0bSAndroid Build Coastguard Worker afl->stage_cycles[STAGE_QUICK] += (afl->fsrv.total_execs - before_eff_execs);
355*08b48e0bSAndroid Build Coastguard Worker
356*08b48e0bSAndroid Build Coastguard Worker cleanup_skipdet:
357*08b48e0bSAndroid Build Coastguard Worker
358*08b48e0bSAndroid Build Coastguard Worker if (fuzz_nearby) {
359*08b48e0bSAndroid Build Coastguard Worker
360*08b48e0bSAndroid Build Coastguard Worker u8 *nearby_bytes = (u8 *)ck_alloc(sizeof(u8) * len);
361*08b48e0bSAndroid Build Coastguard Worker
362*08b48e0bSAndroid Build Coastguard Worker u32 i = 3;
363*08b48e0bSAndroid Build Coastguard Worker while (i < len) {
364*08b48e0bSAndroid Build Coastguard Worker
365*08b48e0bSAndroid Build Coastguard Worker // assume DWORD size, from i - 3 -> i + 3
366*08b48e0bSAndroid Build Coastguard Worker if (skip_eff_map[i]) {
367*08b48e0bSAndroid Build Coastguard Worker
368*08b48e0bSAndroid Build Coastguard Worker u32 fill_length = (i + 3 < len) ? 7 : len - i + 2;
369*08b48e0bSAndroid Build Coastguard Worker memset(nearby_bytes + i - 3, 1, fill_length);
370*08b48e0bSAndroid Build Coastguard Worker i += 3;
371*08b48e0bSAndroid Build Coastguard Worker
372*08b48e0bSAndroid Build Coastguard Worker } else
373*08b48e0bSAndroid Build Coastguard Worker
374*08b48e0bSAndroid Build Coastguard Worker i += 1;
375*08b48e0bSAndroid Build Coastguard Worker
376*08b48e0bSAndroid Build Coastguard Worker }
377*08b48e0bSAndroid Build Coastguard Worker
378*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
379*08b48e0bSAndroid Build Coastguard Worker
380*08b48e0bSAndroid Build Coastguard Worker if (nearby_bytes[i] && !non_eff_bytes[i]) skip_eff_map[i] = 1;
381*08b48e0bSAndroid Build Coastguard Worker
382*08b48e0bSAndroid Build Coastguard Worker }
383*08b48e0bSAndroid Build Coastguard Worker
384*08b48e0bSAndroid Build Coastguard Worker ck_free(nearby_bytes);
385*08b48e0bSAndroid Build Coastguard Worker ck_free(non_eff_bytes);
386*08b48e0bSAndroid Build Coastguard Worker
387*08b48e0bSAndroid Build Coastguard Worker }
388*08b48e0bSAndroid Build Coastguard Worker
389*08b48e0bSAndroid Build Coastguard Worker if (done_eff) {
390*08b48e0bSAndroid Build Coastguard Worker
391*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->continue_inf = 0;
392*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->done_eff = 1;
393*08b48e0bSAndroid Build Coastguard Worker
394*08b48e0bSAndroid Build Coastguard Worker } else {
395*08b48e0bSAndroid Build Coastguard Worker
396*08b48e0bSAndroid Build Coastguard Worker afl->queue_cur->skipdet_e->continue_inf = 1;
397*08b48e0bSAndroid Build Coastguard Worker
398*08b48e0bSAndroid Build Coastguard Worker }
399*08b48e0bSAndroid Build Coastguard Worker
400*08b48e0bSAndroid Build Coastguard Worker return 1;
401*08b48e0bSAndroid Build Coastguard Worker
402*08b48e0bSAndroid Build Coastguard Worker }
403*08b48e0bSAndroid Build Coastguard Worker
404