review done, pray

This commit is contained in:
van Hauser
2020-08-11 16:25:35 +02:00
parent 457f627101
commit 220dc4a43d
6 changed files with 144 additions and 47 deletions

View File

@ -444,7 +444,8 @@ typedef struct afl_state {
python_only, /* Python-only mode */ python_only, /* Python-only mode */
is_main_node, /* if this is the main node */ is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */ is_secondary_node, /* if this is a secondary instance */
taint_needs_splode; /* explode fuzz input */ taint_needs_splode, /* explode fuzz input */
taint_mode;
u32 stats_update_freq; /* Stats update frequency (execs) */ u32 stats_update_freq; /* Stats update frequency (execs) */

View File

@ -961,8 +961,7 @@ void perform_dry_run(afl_state_t *afl) {
} }
/* perform taint gathering on the input seed */ /* perform taint gathering on the input seed */
if (afl->taint_mode) if (afl->taint_mode) perform_taint_run(afl, q, q->fname, use_mem, q->len);
perform_taint_run(afl, q, q->fname, use_mem, q->len);
q = q->next; q = q->next;

View File

@ -462,18 +462,23 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(afl->taint_mode)) { if (unlikely(afl->taint_mode)) {
tmp_val = afl->queue_cycle % 2; tmp_val = afl->queue_cycle % 2; // starts with 1
ret_val = 0; ret_val = 0;
if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry; if (unlikely(afl->queue_cur->cal_failed && !tmp_val)) goto abandon_entry;
if (unlikely(!afl->queue_cur->passed_det) && !tmp_val) goto abandon_entry; if (unlikely(!afl->skip_deterministic && !afl->queue_cur->passed_det &&
if (tmp_val == 1 && !afl->queue_cur->taint_bytes_all) goto abandon_entry; !tmp_val))
if (tmp_val == 0 && !afl->queue_cur->taint_bytes_new) goto abandon_entry; goto abandon_entry;
if ((!afl->queue_cur->taint_bytes_new ||
afl->queue_cur->taint_bytes_new == afl->queue_cur->len) &&
!tmp_val)
goto abandon_entry;
ret_val = 1; ret_val = 1;
s32 dst = 0, i; s32 dst = 0, i;
temp_len = len = afl->queue_cur->len; temp_len = len = afl->queue_cur->len;
s32 j = 0; // tmp
fd = open(afl->queue_cur->fname, O_RDONLY); fd = open(afl->queue_cur->fname, O_RDONLY);
afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
@ -486,15 +491,27 @@ u8 fuzz_one_original(afl_state_t *afl) {
case 1: // fuzz only tainted bytes case 1: // fuzz only tainted bytes
// special case: all or nothing tainted. in this case we act like
// nothing is special. this is not the taint you are looking for ...
if (!afl->queue_cur->taint_bytes_all ||
afl->queue_cur->taint_bytes_all == (u32)len) {
orig_in = in_buf = afl->taint_src;
afl->taint_needs_splode = 0;
break;
}
fd = open(afl->taint_input_file, O_RDONLY); fd = open(afl->taint_input_file, O_RDONLY);
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all; temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all;
orig_in = in_buf = orig_in = in_buf =
mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1) if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->taint_input_file); FATAL("unable to open '%s'", afl->taint_input_file);
close(fd); close(fd);
fd = open(afl->queue_cur->fname_taint, O_RDWR); fd = open(afl->queue_cur->fname_taint, O_RDONLY);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0); MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1) if (fd < 0 || (ssize_t)in_buf == -1)
@ -504,6 +521,29 @@ u8 fuzz_one_original(afl_state_t *afl) {
for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++)
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
// FIXME DEBUG TODO XXX
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
switch (afl->taint_map[i]) {
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position %d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
}
}
if (j != len)
FATAL("different taint values in map vs in queue (%d != %d)", j, len);
break; break;
case 0: // fuzz only newly tainted bytes case 0: // fuzz only newly tainted bytes
@ -511,12 +551,14 @@ u8 fuzz_one_original(afl_state_t *afl) {
fd = open(afl->taint_input_file, O_RDONLY); fd = open(afl->taint_input_file, O_RDONLY);
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new; temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new;
orig_in = in_buf = orig_in = in_buf =
mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1) if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->taint_input_file); FATAL("unable to open '%s'", afl->taint_input_file);
close(fd); close(fd);
u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint); u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint);
if (!fn) FATAL("OOM");
fd = open(fn, O_RDWR); fd = open(fn, O_RDWR);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE, afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0); MAP_PRIVATE, fd, 0);
@ -528,14 +570,35 @@ u8 fuzz_one_original(afl_state_t *afl) {
for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++) for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++)
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i]; if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
// FIXME DEBUG TODO XXX
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
switch (afl->taint_map[i]) {
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position %d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
}
}
if (j != len)
FATAL("different taint values in map vs in queue (%d != %d)", j, len);
break; break;
} }
} else { } else {
afl->taint_needs_splode = 0;
/* Map the test case into memory. */ /* Map the test case into memory. */
fd = open(afl->queue_cur->fname, O_RDONLY); fd = open(afl->queue_cur->fname, O_RDONLY);
@ -574,8 +637,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
* CALIBRATION (only if failed earlier on) * * CALIBRATION (only if failed earlier on) *
*******************************************/ *******************************************/
if (unlikely(afl->queue_cur->cal_failed && if (unlikely(afl->queue_cur->cal_failed)) {
(!afl->taint_needs_splode || tmp_val == 1))) {
u8 res = FSRV_RUN_TMOUT; u8 res = FSRV_RUN_TMOUT;
@ -583,8 +645,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
afl->queue_cur->exec_cksum = 0; afl->queue_cur->exec_cksum = 0;
res = if (unlikely(afl->taint_needs_splode))
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); res = calibrate_case(afl, afl->queue_cur, afl->taint_src,
afl->queue_cycle - 1, 0);
else
res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1,
0);
if (unlikely(res == FSRV_RUN_ERROR)) { if (unlikely(res == FSRV_RUN_ERROR)) {
@ -607,8 +673,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
* TRIMMING * * TRIMMING *
************/ ************/
if (!afl->non_instrumented_mode && !afl->queue_cur->trim_done && if (unlikely(!afl->non_instrumented_mode && !afl->queue_cur->trim_done &&
!afl->disable_trim && !afl->taint_needs_splode) { !afl->disable_trim && !afl->taint_needs_splode)) {
u8 res = trim_case(afl, afl->queue_cur, in_buf); u8 res = trim_case(afl, afl->queue_cur, in_buf);
@ -645,13 +711,26 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) { if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len, int res;
afl->queue_cur->exec_cksum)) { if (unlikely(afl->taint_needs_splode)) {
goto abandon_entry; len = afl->queue_cur->len;
memcpy(out_buf, afl->taint_src, len);
res = input_to_state_stage(afl, afl->taint_src, out_buf, len,
afl->queue_cur->exec_cksum);
// just abandon as success
ret_val = 0;
res = 1;
} else {
res = input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum);
} }
if (unlikely(res)) { goto abandon_entry; }
} }
/* Skip right away if -d is given, if it has not been chosen sufficiently /* Skip right away if -d is given, if it has not been chosen sufficiently
@ -2288,39 +2367,48 @@ havoc_stage:
copy_len = choose_block_len(afl, afl->queue_cur->len - 1); copy_len = choose_block_len(afl, afl->queue_cur->len - 1);
copy_from = rand_below(afl, afl->queue_cur->len - copy_len + 1); copy_from = rand_below(afl, afl->queue_cur->len - copy_len + 1);
copy_to = rand_below(afl, temp_len + 1);
} else { } else {
copy_len = choose_block_len(afl, temp_len - 1); copy_len = choose_block_len(afl, temp_len - 1);
copy_from = rand_below(afl, temp_len - copy_len + 1); copy_from = rand_below(afl, temp_len - copy_len + 1);
copy_to = rand_below(afl, temp_len - copy_len + 1);
} }
copy_to = rand_below(afl, temp_len - copy_len + 1);
if (unlikely(copy_to > (u32)temp_len))
copy_to = rand_below(afl, temp_len);
if (rand_below(afl, 4)) { if (rand_below(afl, 4)) {
if (copy_from != copy_to) { if (copy_from != copy_to) {
if (unlikely(afl->taint_needs_splode)) { if (unlikely(afl->taint_needs_splode)) {
if (copy_to > (u32)temp_len) if (temp_len >= (s32)(copy_to + copy_len)) {
copy_to = rand_below(afl, temp_len);
// fprintf(stderr, "\nout_buf %p + copy_to %u, src %p + %u, memcpy(out_buf + copy_to, afl->taint_src + copy_from,
// copy_len %u -- len %u\n", out_buf , copy_to, afl->taint_src ,
// copy_from, copy_len, afl->taint_len, afl->queue_cur->len);
memmove(out_buf + copy_to, afl->taint_src + copy_from,
copy_len); copy_len);
} else } else {
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch),
copy_to + copy_len);
memcpy(new_buf, in_buf, copy_to);
memcpy(new_buf + copy_to, afl->taint_src + copy_from,
copy_len);
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
temp_len = copy_to + copy_len;
}
} else {
memmove(out_buf + copy_to, out_buf + copy_from, copy_len); memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
} }
}
} else { } else {
memset(out_buf + copy_to, memset(out_buf + copy_to,
@ -2698,7 +2786,7 @@ abandon_entry:
++afl->queue_cur->fuzz_level; ++afl->queue_cur->fuzz_level;
if (afl->taint_needs_splode) { if (unlikely(afl->taint_needs_splode)) {
munmap(afl->taint_src, afl->queue_cur->len); munmap(afl->taint_src, afl->queue_cur->len);
munmap(orig_in, afl->taint_len); munmap(orig_in, afl->taint_len);

View File

@ -420,11 +420,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u8 *mem, u32 len,
afl->last_path_time = get_cur_time(); afl->last_path_time = get_cur_time();
/* trigger the tain gathering if this is not a dry run */ /* trigger the tain gathering if this is not a dry run */
if (afl->taint_mode && mem) { if (afl->taint_mode && mem) { perform_taint_run(afl, q, fname, mem, len); }
perform_taint_run(afl, q, fname, mem, len);
}
/* only redqueen currently uses is_ascii */ /* only redqueen currently uses is_ascii */
if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q); if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(q);

View File

@ -878,9 +878,11 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
if (unlikely(afl->taint_needs_splode)) { if (unlikely(afl->taint_needs_splode)) {
s32 new_len = afl->queue_cur->len + len - afl->taint_len; s32 new_len = afl->queue_cur->len + len - afl->taint_len;
if (new_len < 4) new_len = 4; if (new_len < 4)
if (new_len > MAX_FILE) new_len = MAX_FILE; new_len = 4;
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(in_scratch), new_len); else if (new_len > MAX_FILE)
new_len = MAX_FILE;
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch), new_len);
u32 i, taint = 0; u32 i, taint = 0;
for (i = 0; i < (u32)new_len; i++) { for (i = 0; i < (u32)new_len; i++) {
@ -892,6 +894,8 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
} }
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf; out_buf = new_buf;
len = new_len; len = new_len;

View File

@ -895,8 +895,17 @@ int main(int argc, char **argv_orig, char **envp) {
} }
if (afl->limit_time_sig != 0 && afl->taint_mode) { FATAL("-A and -L are mutually exclusive"); } if (afl->limit_time_sig != 0 && afl->taint_mode) {
if (afl->unicorn_mode != 0 && afl->taint_mode) { FATAL("-A and -U are mutually exclusive"); }
FATAL("-A and -L are mutually exclusive");
}
if (afl->unicorn_mode != 0 && afl->taint_mode) {
FATAL("-A and -U are mutually exclusive");
}
if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; } if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; }
@ -1309,7 +1318,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Taint forkserver successfully started"); OKF("Taint forkserver successfully started");
const rlim_t kStackSize = 256L * 1024L * 1024L; // min stack size = 256 Mb const rlim_t kStackSize = 128L * 1024L * 1024L; // min stack size = 128 Mb
struct rlimit rl; struct rlimit rl;
rl.rlim_cur = kStackSize; rl.rlim_cur = kStackSize;
if (getrlimit(RLIMIT_STACK, &rl) != 0) if (getrlimit(RLIMIT_STACK, &rl) != 0)