aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-bitmap.c2
-rw-r--r--src/afl-fuzz-cmplog.c2
-rw-r--r--src/afl-fuzz-init.c2
-rw-r--r--src/afl-fuzz-mutators.c4
-rw-r--r--src/afl-fuzz-one.c397
-rw-r--r--src/afl-fuzz-run.c24
-rw-r--r--src/afl-fuzz-stats.c12
-rw-r--r--src/afl-sharedmem.c38
8 files changed, 327 insertions, 154 deletions
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 7c2b35d6..26e70d81 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -648,7 +648,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (afl->fsrv.exec_tmout < afl->hang_tmout) {
u8 new_fault;
- len = write_to_testcase(afl, mem, len, 0);
+ len = write_to_testcase(afl, &mem, len, 0);
new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
classify_counts(&afl->fsrv);
diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c
index 7d94085d..258d9ea7 100644
--- a/src/afl-fuzz-cmplog.c
+++ b/src/afl-fuzz-cmplog.c
@@ -49,7 +49,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
- write_to_testcase(afl, out_buf, len, 0);
+ write_to_testcase(afl, (void **)&out_buf, len, 0);
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 05a654c8..6a653a00 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -617,7 +617,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
}
- u32 len = write_to_testcase(afl, mem, st.st_size, 1);
+ u32 len = write_to_testcase(afl, (void **)&mem, st.st_size, 1);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
afl->syncing_party = foreign_name;
afl->queued_imported += save_if_interesting(afl, mem, len, fault);
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index e78e2dc4..9407adfb 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -428,7 +428,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
if (likely(retlen)) {
- retlen = write_to_testcase(afl, retbuf, retlen, 0);
+ retlen = write_to_testcase(afl, (void **)&retbuf, retlen, 0);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
++afl->trim_execs;
@@ -460,6 +460,8 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
}
out_len = retlen;
+ // TODO are we sure that retbuf fits into out_buf if retbuf can actually
+ // increase in size?
memcpy(out_buf, retbuf, retlen);
/* Tell the custom mutator that the trimming was successful */
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index b28ee80a..19f41ebe 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -373,7 +373,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
u32 j;
u32 i;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
- u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum;
+ u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, prev_cksum, _prev_cksum;
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0;
@@ -630,7 +630,14 @@ u8 fuzz_one_original(afl_state_t *afl) {
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
- prev_cksum = afl->queue_cur->exec_cksum;
+ /* Get a clean cksum. */
+
+ if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; }
+
+ prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+ _prev_cksum = prev_cksum;
+
+ /* Now flip bits. */
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -716,7 +723,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* Continue collecting string, but only if the bit flip actually made
any difference - we don't want no-op tokens. */
- if (cksum != afl->queue_cur->exec_cksum) {
+ if (cksum != _prev_cksum) {
if (a_len < MAX_AUTO_EXTRA) {
@@ -839,6 +846,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->stage_max = len;
orig_hit_cnt = new_hit_cnt;
+ prev_cksum = _prev_cksum;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -871,11 +879,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
} else {
- cksum = ~afl->queue_cur->exec_cksum;
+ cksum = ~prev_cksum;
}
- if (cksum != afl->queue_cur->exec_cksum) {
+ if (cksum != prev_cksum) {
eff_map[EFF_APOS(afl->stage_cur)] = 1;
++eff_cnt;
@@ -1779,6 +1787,62 @@ skip_user_extras:
afl->stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_EXTRAS_AO] += afl->stage_max;
+ /* Insertion of auto extras. */
+
+ afl->stage_name = "auto extras (insert)";
+ afl->stage_short = "ext_AI";
+ afl->stage_cur = 0;
+ afl->stage_max = afl->a_extras_cnt * (len + 1);
+
+ orig_hit_cnt = new_hit_cnt;
+
+ ex_tmp = afl_realloc(AFL_BUF_PARAM(ex), len + MAX_DICT_FILE);
+ if (unlikely(!ex_tmp)) { PFATAL("alloc"); }
+
+ for (i = 0; i <= (u32)len; ++i) {
+
+ afl->stage_cur_byte = i;
+
+ for (j = 0; j < afl->a_extras_cnt; ++j) {
+
+ if (len + afl->a_extras[j].len > MAX_FILE) {
+
+ --afl->stage_max;
+ continue;
+
+ }
+
+ /* Insert token */
+ memcpy(ex_tmp + i, afl->a_extras[j].data, afl->a_extras[j].len);
+
+ /* Copy tail */
+ memcpy(ex_tmp + i + afl->a_extras[j].len, out_buf + i, len - i);
+
+#ifdef INTROSPECTION
+ snprintf(afl->mutation, sizeof(afl->mutation),
+ "%s AUTO_EXTRAS_insert-%u-%u", afl->queue_cur->fname, i, j);
+#endif
+
+ if (common_fuzz_stuff(afl, ex_tmp, len + afl->a_extras[j].len)) {
+
+ goto abandon_entry;
+
+ }
+
+ ++afl->stage_cur;
+
+ }
+
+ /* Copy head */
+ ex_tmp[i] = out_buf[i];
+
+ }
+
+ new_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ afl->stage_finds[STAGE_EXTRAS_AI] += new_hit_cnt - orig_hit_cnt;
+ afl->stage_cycles[STAGE_EXTRAS_AI] += afl->stage_max;
+
skip_extras:
/* If we made this to here without jumping to havoc_stage or abandon_entry,
@@ -1905,11 +1969,7 @@ custom_mutator_stage:
}
- /* `(afl->)out_buf` may have been changed by the call to custom_fuzz
- */
- /* TODO: Only do this when `mutated_buf` == `out_buf`? Branch vs
- * Memcpy.
- */
+ /* out_buf may have been changed by the call to custom_fuzz */
memcpy(out_buf, in_buf, len);
}
@@ -2994,7 +3054,8 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
u32 i;
u32 j;
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
- u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum;
+ u64 havoc_queued = 0, orig_hit_cnt, new_hit_cnt = 0, cur_ms_lv, prev_cksum,
+ _prev_cksum;
u32 splice_cycle = 0, perf_score = 100, orig_perf, eff_cnt = 1;
u8 ret_val = 1, doing_det = 0;
@@ -3238,7 +3299,14 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
- prev_cksum = afl->queue_cur->exec_cksum;
+ /* Get a clean cksum. */
+
+ if (common_fuzz_stuff(afl, out_buf, len)) { goto abandon_entry; }
+
+ prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+ _prev_cksum = prev_cksum;
+
+ /* Now flip bits. */
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -3323,7 +3391,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
/* Continue collecting string, but only if the bit flip actually made
any difference - we don't want no-op tokens. */
- if (cksum != afl->queue_cur->exec_cksum) {
+ if (cksum != _prev_cksum) {
if (a_len < MAX_AUTO_EXTRA) {
@@ -3444,6 +3512,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
afl->stage_max = len;
orig_hit_cnt = new_hit_cnt;
+ prev_cksum = _prev_cksum;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -3475,11 +3544,11 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
} else {
- cksum = ~afl->queue_cur->exec_cksum;
+ cksum = ~prev_cksum;
}
- if (cksum != afl->queue_cur->exec_cksum) {
+ if (cksum != prev_cksum) {
eff_map[EFF_APOS(afl->stage_cur)] = 1;
++eff_cnt;
@@ -4367,6 +4436,62 @@ skip_user_extras:
afl->stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt;
afl->stage_cycles[STAGE_EXTRAS_AO] += afl->stage_max;
+ /* Insertion of auto extras. */
+
+ afl->stage_name = "auto extras (insert)";
+ afl->stage_short = "ext_AI";
+ afl->stage_cur = 0;
+ afl->stage_max = afl->a_extras_cnt * (len + 1);
+
+ orig_hit_cnt = new_hit_cnt;
+
+ ex_tmp = afl_realloc(AFL_BUF_PARAM(ex), len + MAX_DICT_FILE);
+ if (unlikely(!ex_tmp)) { PFATAL("alloc"); }
+
+ for (i = 0; i <= (u32)len; ++i) {
+
+ afl->stage_cur_byte = i;
+
+ for (j = 0; j < afl->a_extras_cnt; ++j) {
+
+ if (len + afl->a_extras[j].len > MAX_FILE) {
+
+ --afl->stage_max;
+ continue;
+
+ }
+
+ /* Insert token */
+ memcpy(ex_tmp + i, afl->a_extras[j].data, afl->a_extras[j].len);
+
+ /* Copy tail */
+ memcpy(ex_tmp + i + afl->a_extras[j].len, out_buf + i, len - i);
+
+#ifdef INTROSPECTION
+ snprintf(afl->mutation, sizeof(afl->mutation),
+ "%s MOPT_AUTO_EXTRAS_insert-%u-%u", afl->queue_cur->fname, i, j);
+#endif
+
+ if (common_fuzz_stuff(afl, ex_tmp, len + afl->a_extras[j].len)) {
+
+ goto abandon_entry;
+
+ }
+
+ ++afl->stage_cur;
+
+ }
+
+ /* Copy head */
+ ex_tmp[i] = out_buf[i];
+
+ } /* for i = 0; i <= len */
+
+ new_hit_cnt = afl->queued_items + afl->saved_crashes;
+
+ afl->stage_finds[STAGE_EXTRAS_AI] += new_hit_cnt - orig_hit_cnt;
+ afl->stage_cycles[STAGE_EXTRAS_AI] += afl->stage_max;
+
skip_extras:
/* If we made this to here without jumping to havoc_stage or abandon_entry,
@@ -4464,14 +4589,14 @@ pacemaker_fuzzing:
havoc_queued = afl->queued_items;
- u32 r_max;
+ u32 r_max, r;
- r_max = 15 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0);
+ r_max = 16 + ((afl->extras_cnt + afl->a_extras_cnt) ? 2 : 0);
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
/* add expensive havoc cases here, they are activated after a full
- cycle without finds happened */
+ cycle without any finds happened */
++r_max;
@@ -4497,7 +4622,7 @@ pacemaker_fuzzing:
for (i = 0; i < use_stacking; ++i) {
- switch (select_algorithm(afl, r_max)) {
+ switch (r = (select_algorithm(afl, r_max))) {
case 0:
/* Flip a single bit somewhere. Spooky! */
@@ -4914,192 +5039,196 @@ pacemaker_fuzzing:
} /* case 15 */
+ default: {
+
/* Values 16 and 17 can be selected only if there are any extras
present in the dictionaries. */
- case 16: {
+ r -= 16;
+
+ if (r == 0 && (afl->extras_cnt || afl->a_extras_cnt)) {
- /* Overwrite bytes with an extra. */
+ /* Overwrite bytes with an extra. */
- if (!afl->extras_cnt ||
- (afl->a_extras_cnt && rand_below(afl, 2))) {
+ if (!afl->extras_cnt ||
+ (afl->a_extras_cnt && rand_below(afl, 2))) {
- /* No user-specified extras or odds in our favor. Let's use an
- auto-detected one. */
+ /* No user-specified extras or odds in our favor. Let's use an
+ auto-detected one. */
- u32 use_extra = rand_below(afl, afl->a_extras_cnt);
- u32 extra_len = afl->a_extras[use_extra].len;
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
+ u32 extra_len = afl->a_extras[use_extra].len;
- if (extra_len > (u32)temp_len) break;
+ if (extra_len > (u32)temp_len) break;
- u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
+ u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
- extra_len);
+ memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
+ extra_len);
- } else {
+ } else {
- /* No auto extras or odds in our favor. Use the dictionary. */
+ /* No auto extras or odds in our favor. Use the dictionary. */
- u32 use_extra = rand_below(afl, afl->extras_cnt);
- u32 extra_len = afl->extras[use_extra].len;
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
- if (extra_len > (u32)temp_len) break;
+ if (extra_len > (u32)temp_len) break;
- u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
+ u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memcpy(out_buf + insert_at, afl->extras[use_extra].data,
- extra_len);
+ memcpy(out_buf + insert_at, afl->extras[use_extra].data,
+ extra_len);
- }
+ }
- MOpt_globals.cycles_v2[STAGE_OverWriteExtra]++;
+ MOpt_globals.cycles_v2[STAGE_OverWriteExtra]++;
- break;
+ break;
- }
+ }
/* Insert an extra. */
- case 17: {
+ else if (r == 1 && (afl->extras_cnt || afl->a_extras_cnt)) {
- u32 use_extra, extra_len,
- insert_at = rand_below(afl, temp_len + 1);
- u8 *ptr;
+ u32 use_extra, extra_len,
+ insert_at = rand_below(afl, temp_len + 1);
+ u8 *ptr;
- /* Insert an extra. Do the same dice-rolling stuff as for the
- previous case. */
+ /* Insert an extra. Do the same dice-rolling stuff as for the
+ previous case. */
- if (!afl->extras_cnt ||
- (afl->a_extras_cnt && rand_below(afl, 2))) {
+ if (!afl->extras_cnt ||
+ (afl->a_extras_cnt && rand_below(afl, 2))) {
- use_extra = rand_below(afl, afl->a_extras_cnt);
- extra_len = afl->a_extras[use_extra].len;
- ptr = afl->a_extras[use_extra].data;
+ use_extra = rand_below(afl, afl->a_extras_cnt);
+ extra_len = afl->a_extras[use_extra].len;
+ ptr = afl->a_extras[use_extra].data;
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- } else {
+ } else {
- use_extra = rand_below(afl, afl->extras_cnt);
- extra_len = afl->extras[use_extra].len;
- ptr = afl->extras[use_extra].data;
+ use_extra = rand_below(afl, afl->extras_cnt);
+ extra_len = afl->extras[use_extra].len;
+ ptr = afl->extras[use_extra].data;
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u",
- insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " EXTRA_INSERT-%u-%u", insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- }
-
- if (temp_len + extra_len >= MAX_FILE) break;
+ }
- out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
- if (unlikely(!out_buf)) { PFATAL("alloc"); }
+ if (temp_len + extra_len >= MAX_FILE) break;
- /* Tail */
- memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
- temp_len - insert_at);
+ out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
+ if (unlikely(!out_buf)) { PFATAL("alloc"); }
- /* Inserted part */
- memcpy(out_buf + insert_at, ptr, extra_len);
+ /* Tail */
+ memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
+ temp_len - insert_at);
- temp_len += extra_len;
- MOpt_globals.cycles_v2[STAGE_InsertExtra]++;
- break;
+ /* Inserted part */
+ memcpy(out_buf + insert_at, ptr, extra_len);
- }
+ temp_len += extra_len;
+ MOpt_globals.cycles_v2[STAGE_InsertExtra]++;
+ break;
- default: {
+ } else {
- if (unlikely(afl->ready_for_splicing_count < 2)) break;
+ if (unlikely(afl->ready_for_splicing_count < 2)) break;
- u32 tid;
- do {
+ u32 tid;
+ do {
- tid = rand_below(afl, afl->queued_items);
+ tid = rand_below(afl, afl->queued_items);
- } while (tid == afl->current_entry ||
+ } while (tid == afl->current_entry ||
- afl->queue_buf[tid]->len < 4);
+ afl->queue_buf[tid]->len < 4);
- /* Get the testcase for splicing. */
- struct queue_entry *target = afl->queue_buf[tid];
- u32 new_len = target->len;
- u8 * new_buf = queue_testcase_get(afl, target);
+ /* Get the testcase for splicing. */
+ struct queue_entry *target = afl->queue_buf[tid];
+ u32 new_len = target->len;
+ u8 * new_buf = queue_testcase_get(afl, target);
- if ((temp_len >= 2 && rand_below(afl, 2)) ||
- temp_len + HAVOC_BLK_XL >= MAX_FILE) {
+ if ((temp_len >= 2 && rand_below(afl, 2)) ||
+ temp_len + HAVOC_BLK_XL >= MAX_FILE) {
- /* overwrite mode */
+ /* overwrite mode */
- u32 copy_from, copy_to, copy_len;
+ u32 copy_from, copy_to, copy_len;
- copy_len = choose_block_len(afl, new_len - 1);
- if (copy_len > temp_len) copy_len = temp_len;
+ copy_len = choose_block_len(afl, new_len - 1);
+ if (copy_len > temp_len) copy_len = temp_len;
- copy_from = rand_below(afl, new_len - copy_len + 1);
- copy_to = rand_below(afl, temp_len - copy_len + 1);
+ copy_from = rand_below(afl, new_len - copy_len + 1);
+ copy_to = rand_below(afl, temp_len - copy_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to,
- copy_len, target->fname);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to,
+ copy_len, target->fname);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
+ memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
- } else {
+ } else {
- /* insert mode */
+ /* insert mode */
- u32 clone_from, clone_to, clone_len;
+ u32 clone_from, clone_to, clone_len;
- clone_len = choose_block_len(afl, new_len);
- clone_from = rand_below(afl, new_len - clone_len + 1);
- clone_to = rand_below(afl, temp_len + 1);
+ clone_len = choose_block_len(afl, new_len);
+ clone_from = rand_below(afl, new_len - clone_len + 1);
+ clone_to = rand_below(afl, temp_len + 1);
- u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch),
- temp_len + clone_len + 1);
- if (unlikely(!temp_buf)) { PFATAL("alloc"); }
+ u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch),
+ temp_len + clone_len + 1);
+ if (unlikely(!temp_buf)) { PFATAL("alloc"); }
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to,
- clone_len, target->fname);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to,
+ clone_len, target->fname);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- /* Head */
+ /* Head */
- memcpy(temp_buf, out_buf, clone_to);
+ memcpy(temp_buf, out_buf, clone_to);
- /* Inserted part */
+ /* Inserted part */
- memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
+ memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
- /* Tail */
- memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
- temp_len - clone_to);
+ /* Tail */
+ memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
+ temp_len - clone_to);
- out_buf = temp_buf;
- afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
- temp_len += clone_len;
+ out_buf = temp_buf;
+ afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
+ temp_len += clone_len;
- }
+ }
- MOpt_globals.cycles_v2[STAGE_Splice]++;
- break;
+ MOpt_globals.cycles_v2[STAGE_Splice]++;
+ break;
+
+ }
} // end of default:
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index ffba3475..09e773f0 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -74,7 +74,7 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) {
rewound and truncated. */
u32 __attribute__((hot))
-write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
+write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
#ifdef _AFL_DOCUMENT_MUTATIONS
s32 doc_fd;
@@ -86,7 +86,7 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION)) >=
0) {
- if (write(doc_fd, mem, len) != len)
+ if (write(doc_fd, *mem, len) != len)
PFATAL("write to mutation file failed: %s", fn);
close(doc_fd);
@@ -97,7 +97,7 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
if (unlikely(afl->custom_mutators_count)) {
ssize_t new_size = len;
- u8 * new_mem = mem;
+ u8 * new_mem = *mem;
u8 * new_buf = NULL;
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
@@ -130,8 +130,14 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
}
+ if (new_mem != *mem) {
+
+ *mem = new_mem;
+
+ }
+
/* everything as planned. use the potentially new data. */
- afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size);
+ afl_fsrv_write_to_testcase(&afl->fsrv, *mem, new_size);
len = new_size;
} else {
@@ -147,7 +153,7 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
}
/* boring uncustom. */
- afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
+ afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len);
}
@@ -370,7 +376,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
/* we need a dummy run if this is LTO + cmplog */
if (unlikely(afl->shm.cmplog_mode)) {
- (void)write_to_testcase(afl, use_mem, q->len, 1);
+ (void)write_to_testcase(afl, (void **)&use_mem, q->len, 1);
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
@@ -413,7 +419,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
u64 cksum;
- (void)write_to_testcase(afl, use_mem, q->len, 1);
+ (void)write_to_testcase(afl, (void **)&use_mem, q->len, 1);
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
@@ -724,7 +730,7 @@ void sync_fuzzers(afl_state_t *afl) {
/* See what happens. We rely on save_if_interesting() to catch major
errors and save the test case. */
- (void)write_to_testcase(afl, mem, st.st_size, 1);
+ (void)write_to_testcase(afl, (void **)&mem, st.st_size, 1);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
@@ -967,7 +973,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
u8 fault;
- len = write_to_testcase(afl, out_buf, len, 0);
+ len = write_to_testcase(afl, (void **)&out_buf, len, 0);
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 9737c692..5b237748 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -1021,13 +1021,15 @@ void show_stats_normal(afl_state_t *afl) {
if (unlikely(!afl->skip_deterministic)) {
- sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]),
+ u_stringify_int(IB(6), afl->stage_finds[STAGE_EXTRAS_AI]),
+ u_stringify_int(IB(7), afl->stage_cycles[STAGE_EXTRAS_AI]));
} else if (unlikely(!afl->extras_cnt || afl->custom_only)) {
@@ -1839,13 +1841,15 @@ void show_stats_pizza(afl_state_t *afl) {
if (unlikely(!afl->skip_deterministic)) {
- sprintf(tmp, "%s/%s, %s/%s, %s/%s",
+ sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
- u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
+ u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]),
+ u_stringify_int(IB(6), afl->stage_finds[STAGE_EXTRAS_AI]),
+ u_stringify_int(IB(7), afl->stage_cycles[STAGE_EXTRAS_AI]));
} else if (unlikely(!afl->extras_cnt || afl->custom_only)) {
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 8d58bb3e..b48c6fb3 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -107,7 +107,7 @@ void afl_shm_deinit(sharedmem_t *shm) {
if (shm->cmp_map != NULL) {
munmap(shm->cmp_map, shm->map_size);
- shm->map = NULL;
+ shm->cmp_map = NULL;
}
@@ -153,6 +153,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
shm->g_shm_fd = -1;
shm->cmplog_g_shm_fd = -1;
+ const int shmflags = O_RDWR | O_EXCL;
+
/* ======
generate random file name for multi instance
@@ -161,9 +163,39 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
so we do this worse workaround */
snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
+ #ifdef SHM_LARGEPAGE_ALLOC_DEFAULT
+ /* trying to get large memory segment optimised and monitorable separately as
+ * such */
+ static size_t sizes[4] = {(size_t)-1};
+ static int psizes = 0;
+ int i;
+ if (sizes[0] == (size_t)-1) { psizes = getpagesizes(sizes, 4); }
+
+ /* very unlikely to fail even if the arch supports only two sizes */
+ if (likely(psizes > 0)) {
+
+ for (i = psizes - 1; shm->g_shm_fd == -1 && i >= 0; --i) {
+
+ if (sizes[i] == 0 || map_size % sizes[i]) { continue; }
+
+ shm->g_shm_fd =
+ shm_create_largepage(shm->g_shm_file_path, shmflags, i,
+ SHM_LARGEPAGE_ALLOC_DEFAULT, DEFAULT_PERMISSION);
+
+ }
+
+ }
+
+ #endif
+
/* create the shared memory segment as if it was a file */
- shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
- DEFAULT_PERMISSION);
+ if (shm->g_shm_fd == -1) {
+
+ shm->g_shm_fd =
+ shm_open(shm->g_shm_file_path, shmflags | O_CREAT, DEFAULT_PERMISSION);
+
+ }
+
if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */