about summary refs log tree commit diff
path: root/src/afl-fuzz-run.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-fuzz-run.c')
-rw-r--r--src/afl-fuzz-run.c83
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;
 
   }