afl-fuzz.c
static u8 run_target(s32 * child_PID, s32 * fsrv_ctlFD, s32 * fsrv_stFD, u32 timeout) {

  /* Runs either binary on current testcase, and report back exit code. */

  int status;
  static int prev_timed_out = 0;
  static struct itimerval it;
  child_timed_out = 0;

  /* After this memset, trace_bits[] are effectively volatile, so we
     must prevent any earlier operations from venturing into that
     territory. */

  memset(trace_bits, 0, afl_map_size);
  MEM_BARRIER();

  /* Forkserver is up, so tell it to have at it (control pipe), then read back PID. 
   * A message length of 4 indicates successful communication with the forkserver. */

  if (write(*fsrv_ctlFD, &prev_timed_out, 4) != 4) {
    if (stop_soon) return 0;
    FATAL("Unable to request new process from fork server (OOM?)");
  }

  /* Read status message and check message length. */

  if (read(*fsrv_stFD, child_PID, 4) != 4) {
    if (stop_soon) return 0;
    FATAL("Unable to request new process from fork server (OOM?)");
  }

  /* Verify child PID isn't corrupt or active. */

  if (*child_PID <= 0) {
    if (stop_soon) return 0;
    FATAL("Fork server is misbehaving (OOM?)");
  }

  /* Configure timer. */

  it.it_value.tv_sec = (timeout / 1000);
  it.it_value.tv_usec = (timeout % 1000) * 1000;
  setitimer(ITIMER_REAL, &it, NULL);

  /* Read and check message length. */

  if (read(*fsrv_stFD, &status, 4) != 4) {
    FATAL("Unable to communicate with fork server (OOM?)");
  }

  if (!WIFSTOPPED(status)) 
    *child_PID = 0;

  /* Deactivate timer. */

  it.it_value.tv_sec = 0;
  it.it_value.tv_usec = 0;
  setitimer(ITIMER_REAL, &it, NULL);

  total_execs++;

  /* Any subsequent operations on trace_bits must not be moved by the
     compiler below this point. Past this location, trace_bits[] behave
     very normally and do not have to be treated as volatile. */

  MEM_BARRIER();

#ifdef __x86_64__
  classify_counts((u64*)trace_bits);
#else
  classify_counts((u32*)trace_bits);
#endif /* ^__x86_64__ */

  prev_timed_out = child_timed_out;

  /* Report outcome to caller. */

  if (WIFSIGNALED(status) && !stop_soon) {

    kill_signal = WTERMSIG(status);

    /* We process all timeout-producing testcases (including SIGTRAPs) as timeouts. */
    if (child_timed_out && (kill_signal == SIGKILL || kill_signal == SIGTRAP)) return FAULT_TMOUT; 

    return FAULT_CRASH;
  }

  return FAULT_NONE;

}
/* Execute target application, monitoring for timeouts. Return status
   information. The called program will update trace_bits[]. */
Execute target application, monitoring for timeouts. Return status
information. The called program will update trace_bits[].
Execute target application monitoring for timeouts . Return status information . The called program will update trace_bits [] .
static u8 run_target(s32 * child_PID, s32 * fsrv_ctlFD, s32 * fsrv_stFD, u32 timeout) {
  int status;
  static int prev_timed_out = 0;
  static struct itimerval it;
  child_timed_out = 0;
  memset(trace_bits, 0, afl_map_size);
  MEM_BARRIER();
  if (write(*fsrv_ctlFD, &prev_timed_out, 4) != 4) {
    if (stop_soon) return 0;
    FATAL("Unable to request new process from fork server (OOM?)");
  }
  if (read(*fsrv_stFD, child_PID, 4) != 4) {
    if (stop_soon) return 0;
    FATAL("Unable to request new process from fork server (OOM?)");
  }
  if (*child_PID <= 0) {
    if (stop_soon) return 0;
    FATAL("Fork server is misbehaving (OOM?)");
  }
  it.it_value.tv_sec = (timeout / 1000);
  it.it_value.tv_usec = (timeout % 1000) * 1000;
  setitimer(ITIMER_REAL, &it, NULL);
  if (read(*fsrv_stFD, &status, 4) != 4) {
    FATAL("Unable to communicate with fork server (OOM?)");
  }
  if (!WIFSTOPPED(status)) 
    *child_PID = 0;
  it.it_value.tv_sec = 0;
  it.it_value.tv_usec = 0;
  setitimer(ITIMER_REAL, &it, NULL);
  total_execs++;
  MEM_BARRIER();
#ifdef __x86_64__
  classify_counts((u64*)trace_bits);
#else
  classify_counts((u32*)trace_bits);
#endif 
  prev_timed_out = child_timed_out;
  if (WIFSIGNALED(status) && !stop_soon) {
    kill_signal = WTERMSIG(status);
    if (child_timed_out && (kill_signal == SIGKILL || kill_signal == SIGTRAP)) return FAULT_TMOUT; 
    return FAULT_CRASH;
  }
  return FAULT_NONE;
}
static u8 run_target ( s32 * child_PID , s32 * fsrv_ctlFD , s32 * fsrv_stFD , u32 timeout ) { int status ; static int prev_timed_out = 0 ; static struct itimerval it ; child_timed_out = 0 ; memset ( trace_bits , 0 , afl_map_size ) ; MEM_BARRIER ( ) ; if ( write ( * fsrv_ctlFD , & prev_timed_out , 4 ) != 4 ) { if ( stop_soon ) return 0 ; FATAL ( " " ) ; } if ( read ( * fsrv_stFD , child_PID , 4 ) != 4 ) { if ( stop_soon ) return 0 ; FATAL ( " " ) ; } if ( * child_PID <= 0 ) { if ( stop_soon ) return 0 ; FATAL ( " " ) ; } it . it_value . tv_sec = ( timeout / 1000 ) ; it . it_value . tv_usec = ( timeout % 1000 ) * 1000 ; setitimer ( ITIMER_REAL , & it , NULL ) ; if ( read ( * fsrv_stFD , & status , 4 ) != 4 ) { FATAL ( " " ) ; } if ( ! WIFSTOPPED ( status ) ) * child_PID = 0 ; it . it_value . tv_sec = 0 ; it . it_value . tv_usec = 0 ; setitimer ( ITIMER_REAL , & it , NULL ) ; total_execs ++ ; MEM_BARRIER ( ) ; #ifdef __x86_64__ classify_counts ( ( u64 * ) trace_bits ) ; #else classify_counts ( ( u32 * ) trace_bits ) ; #endif prev_timed_out = child_timed_out ; if ( WIFSIGNALED ( status ) && ! stop_soon ) { kill_signal = WTERMSIG ( status ) ; if ( child_timed_out && ( kill_signal == SIGKILL || kill_signal == SIGTRAP ) ) return FAULT_TMOUT ; return FAULT_CRASH ; } return FAULT_NONE ; }
Execute target application, monitoring for timeouts.
Execute target application monitoring for timeouts .
/* Runs either binary on current testcase, and report back exit code. */ /* After this memset, trace_bits[] are effectively volatile, so we
     must prevent any earlier operations from venturing into that
     territory. */ /* Forkserver is up, so tell it to have at it (control pipe), then read back PID. 
   * A message length of 4 indicates successful communication with the forkserver. */ /* Read status message and check message length. */ /* Verify child PID isn't corrupt or active. */ /* Configure timer. */ /* Read and check message length. */ /* Deactivate timer. */ /* Any subsequent operations on trace_bits must not be moved by the
     compiler below this point. Past this location, trace_bits[] behave
     very normally and do not have to be treated as volatile. */ /* ^__x86_64__ */ /* Report outcome to caller. */ /* We process all timeout-producing testcases (including SIGTRAPs) as timeouts. */