diff options
Diffstat (limited to 'src/afl-fuzz-run.c')
-rw-r--r-- | src/afl-fuzz-run.c | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 8c4b5941..5875eb68 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -33,13 +33,10 @@ u8 run_target(afl_state_t *afl, u32 timeout) { s32 res; - int sret; + u32 exec_ms; - fd_set readfds; - - struct timeval it; - int status = 0; - u32 tb4; + int status = 0; + u32 tb4; afl->fsrv.child_timed_out = 0; @@ -70,26 +67,20 @@ u8 run_target(afl_state_t *afl, u32 timeout) { if (afl->fsrv.child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)"); - /* use select to monitor the forkserver for timeouts. */ - - FD_ZERO(&readfds); - FD_SET(afl->fsrv.fsrv_st_fd, &readfds); - it.tv_sec = ((timeout) / 1000); - it.tv_usec = ((timeout) % 1000) * 1000; - - sret = select(afl->fsrv.fsrv_st_fd + 1, &readfds, NULL, NULL, &it); + exec_ms = read_timed(afl->fsrv.fsrv_st_fd, &status, 4, timeout); - if (sret == 0) { + if (exec_ms > timeout) { /* If there was no response from forkserver after timeout seconds, we kill the child. The forkserver should inform us afterwards */ kill(afl->fsrv.child_pid, SIGKILL); afl->fsrv.child_timed_out = 1; + if (read(afl->fsrv.fsrv_st_fd, &status, 4) < 4) exec_ms = 0; } - if ((res = read(afl->fsrv.fsrv_st_fd, &status, 4)) != 4) { + if (!exec_ms) { if (afl->stop_soon) return 0; SAYF("\n" cLRD "[-] " cRST @@ -176,20 +167,16 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { s32 fd = afl->fsrv.out_fd; #ifdef _AFL_DOCUMENT_MUTATIONS - s32 doc_fd; - char *fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir, + s32 doc_fd; + char fn[PATH_MAX]; + snprintf(fn, PATH_MAX, ("%s/mutations/%09u:%s", afl->out_dir, afl->document_counter++, describe_op(afl, 0)); - if (fn != NULL) { - - if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { - - if (write(doc_fd, mem, len) != len) - PFATAL("write to mutation file failed: %s", fn); - close(doc_fd); - } + if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { - ck_free(fn); + if (write(doc_fd, mem, len) != len) + PFATAL("write to mutation file failed: %s", fn); + close(doc_fd); } @@ -214,16 +201,22 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) { lseek(fd, 0, SEEK_SET); - if (afl->mutator && afl->mutator->afl_custom_pre_save) { + if (unlikely(afl->mutator && afl->mutator->afl_custom_pre_save)) { + + u8 *new_buf = NULL; + + size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem, + len, &new_buf); - u8 * new_data; - size_t new_size = - afl->mutator->afl_custom_pre_save(afl, mem, len, &new_data); - ck_write(fd, new_data, new_size, afl->fsrv.out_file); - ck_free(new_data); + if (unlikely(!new_buf)) + FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size); + + /* everything as planned. use the new data. */ + ck_write(fd, new_buf, new_size, afl->fsrv.out_file); } else { + /* boring uncustom. */ ck_write(fd, mem, len, afl->fsrv.out_file); } @@ -505,8 +498,8 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_cur = 0; afl->stage_max = 0; - /* For every file queued by this fuzzer, parse ID and see if we have looked - at it before; exec a test case if not. */ + /* For every file queued by this fuzzer, parse ID and see if we have + looked at it before; exec a test case if not. */ while ((qd_ent = readdir(qd))) { @@ -615,7 +608,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Select initial chunk len, starting with large steps. */ - len_p2 = next_p2(q->len); + len_p2 = next_pow2(q->len); remove_len = MAX(len_p2 / TRIM_START_STEPS, TRIM_MIN_BYTES); @@ -627,8 +620,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 remove_pos = remove_len; sprintf(afl->stage_name_buf, "trim %s/%s", - u_stringify_int(val_bufs[0], remove_len), - u_stringify_int(val_bufs[1], remove_len)); + u_stringify_int(val_bufs[0], remove_len), + u_stringify_int(val_bufs[1], remove_len)); afl->stage_cur = 0; afl->stage_max = q->len / remove_len; @@ -645,7 +638,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (afl->stop_soon || fault == FAULT_ERROR) goto abort_trimming; - /* Note that we don't keep track of crashes or hangs here; maybe TODO? */ + /* Note that we don't keep track of crashes or hangs here; maybe TODO? + */ cksum = hash32(afl->fsrv.trace_bits, MAP_SIZE, HASH_CONST); @@ -659,7 +653,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { u32 move_tail = q->len - remove_pos - trim_avail; q->len -= trim_avail; - len_p2 = next_p2(q->len); + len_p2 = next_pow2(q->len); memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, move_tail); @@ -734,8 +728,13 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { if (afl->post_handler) { - out_buf = afl->post_handler(out_buf, &len); - if (!out_buf || !len) return 0; + u8 *post_buf = NULL; + + size_t post_len = + afl->post_handler(afl->post_data, out_buf, len, &post_buf); + if (!post_buf || !post_len) return 0; + out_buf = post_buf; + len = post_len; } |