about summary refs log tree commit diff
path: root/include/afl-fuzz.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/afl-fuzz.h')
-rw-r--r--include/afl-fuzz.h129
1 files changed, 83 insertions, 46 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 7dddefb0..56135d0e 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -239,8 +239,6 @@ enum {
 
 };
 
-extern u8 *doc_path;                    /* gath to documentation dir        */
-
 /* Python stuff */
 #ifdef USE_PYTHON
 
@@ -290,8 +288,20 @@ typedef struct py_mutator {
 
   PyObject *py_module;
   PyObject *py_functions[PY_FUNC_COUNT];
-  void *afl_state;
-  void *py_data;
+  void *    afl_state;
+  void *    py_data;
+
+  u8 *   fuzz_buf;
+  size_t fuzz_size;
+
+  u8 *   pre_save_buf;
+  size_t pre_save_size;
+
+  u8 *   trim_buf;
+  size_t trim_size;
+
+  u8 *   havoc_buf;
+  size_t havoc_size;
 
 } py_mutator_t;
 
@@ -472,11 +482,6 @@ typedef struct afl_state {
       unique_tmouts,                    /* Timeouts with unique signatures  */
       unique_hangs,                     /* Hangs with unique signatures     */
       total_execs,                      /* Total execve() calls             */
-      slowest_exec_ms,                  /* Slowest testcase non hang in ms  */
-      start_time,                       /* Unix start time (ms)             */
-      last_path_time,                   /* Time for most recent path (ms)   */
-      last_crash_time,                  /* Time for most recent crash (ms)  */
-      last_hang_time,                   /* Time for most recent hang (ms)   */
       last_crash_execs,                 /* Exec counter at last crash       */
       queue_cycle,                      /* Queue round counter              */
       cycles_wo_finds,                  /* Cycles without any new paths     */
@@ -484,9 +489,14 @@ typedef struct afl_state {
       bytes_trim_in,                    /* Bytes coming into the trimmer    */
       bytes_trim_out,                   /* Bytes coming outa the trimmer    */
       blocks_eff_total,                 /* Blocks subject to effector maps  */
-      blocks_eff_select;                /* Blocks selected as fuzzable      */
+      blocks_eff_select,                /* Blocks selected as fuzzable      */
+      start_time,                       /* Unix start time (ms)             */
+      last_path_time,                   /* Time for most recent path (ms)   */
+      last_crash_time,                  /* Time for most recent crash (ms)  */
+      last_hang_time;                   /* Time for most recent hang (ms)   */
 
-  u32 subseq_tmouts;                    /* Number of timeouts in a row      */
+  u32 slowest_exec_ms,                  /* Slowest testcase non hang in ms  */
+      subseq_tmouts;                    /* Number of timeouts in a row      */
 
   u8 *stage_name,                       /* Name of the current fuzz stage   */
       *stage_short,                     /* Short stage name                 */
@@ -541,7 +551,11 @@ typedef struct afl_state {
   struct extra_data *a_extras;          /* Automatically selected extras    */
   u32                a_extras_cnt;      /* Total number of tokens available */
 
-  u8 *(*post_handler)(u8 *buf, u32 *len);
+  /* afl_postprocess API */
+  void *(*post_init)(struct afl_state *afl);
+  size_t (*post_handler)(void *data, u8 *buf, u32 len, u8 **out_buf);
+  void *(*post_deinit)(void *data);
+  void *post_data;
 
   /* CmpLog */
 
@@ -550,9 +564,6 @@ typedef struct afl_state {
 
   /* Custom mutators */
   struct custom_mutator *mutator;
-#ifdef USE_PYTHON
-  struct custom_mutator *py_mutator;
-#endif
 
   /* cmplog forkserver ids */
   s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
@@ -580,6 +591,26 @@ typedef struct afl_state {
   u8 clean_trace_custom[MAP_SIZE];
   u8 first_trace[MAP_SIZE];
 
+  /*needed for afl_fuzz_one */
+  // TODO: see which we can reuse
+  u8 *   out_buf;
+  size_t out_size;
+
+  u8 *   out_scratch_buf;
+  size_t out_scratch_size;
+
+  u8 *   eff_buf;
+  size_t eff_size;
+
+  u8 *   in_buf;
+  size_t in_size;
+
+  u8 *   in_scratch_buf;
+  size_t in_scratch_size;
+
+  u8 *   ex_buf;
+  size_t ex_size;
+
 } afl_state_t;
 
 /* A global pointer to all instances is needed (for now) for signals to arrive
@@ -591,8 +622,10 @@ struct custom_mutator {
 
   const char *name;
   void *      dh;
+  u8 *        pre_save_buf;
+  size_t      pre_save_size;
 
-  void *data;    /* custom mutator data ptr */
+  void *data;                                    /* custom mutator data ptr */
 
   /* hooks for the custom mutator function */
 
@@ -611,16 +644,18 @@ struct custom_mutator {
    * (Optional for now. Required in the future)
    *
    * @param data pointer returned in afl_custom_init for this fuzz case
-   * @param[inout] buf Pointer to the input data to be mutated and the mutated
+   * @param[in] buf Pointer to the input data to be mutated and the mutated
    *     output
    * @param[in] buf_size Size of the input/output data
+   * @param[out] out_buf the new buffer. We may reuse *buf if large enough.
+   *             *out_buf = NULL is treated as FATAL.
    * @param[in] add_buf Buffer containing the additional test case
    * @param[in] add_buf_size Size of the additional test case
    * @param[in] max_size Maximum size of the mutated output. The mutation must
    * not produce data larger than max_size.
    * @return Size of the mutated output.
    */
-  size_t (*afl_custom_fuzz)(void *data, u8 **buf, size_t buf_size,
+  size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf,
                             u8 *add_buf, size_t add_buf_size, size_t max_size);
 
   /**
@@ -633,10 +668,10 @@ struct custom_mutator {
    * @param[in] data pointer returned in afl_custom_init for this fuzz case
    * @param[in] buf Buffer containing the test case to be executed
    * @param[in] buf_size Size of the test case
-   * @param[out] out_buf Pointer to the buffer of storing the test case after
-   *     processing. External library should allocate memory for out_buf. AFL++
-   *     will release the memory after saving the test case.
-   * @return Size of the output buffer after processing
+   * @param[out] out_buf Pointer to the buffer storing the test case after
+   *     processing. External library should allocate memory for out_buf.
+   *     It can chose to alter buf in-place, if the space is large enough.
+   * @return Size of the output buffer.
    */
   size_t (*afl_custom_pre_save)(void *data, u8 *buf, size_t buf_size,
                                 u8 **out_buf);
@@ -660,9 +695,10 @@ struct custom_mutator {
    * @param data pointer returned in afl_custom_init for this fuzz case
    * @param buf Buffer containing the test case
    * @param buf_size Size of the test case
-   * @return The amount of possible iteration steps to trim the input
+   * @return The amount of possible iteration steps to trim the input.
+   *        Negative on error.
    */
-  u32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size);
+  s32 (*afl_custom_init_trim)(void *data, u8 *buf, size_t buf_size);
 
   /**
    * This method is called for each trimming operation. It doesn't have any
@@ -677,11 +713,11 @@ struct custom_mutator {
    *
    * @param data pointer returned in afl_custom_init for this fuzz case
    * @param[out] out_buf Pointer to the buffer containing the trimmed test case.
-   *     External library should allocate memory for out_buf. AFL++ will release
-   *     the memory after saving the test case.
-   * @param[out] out_buf_size Pointer to the size of the trimmed test case
+   *             The library can reuse a buffer for each call
+   *             and will have to free the buf (for example in deinit)
+   * @return the size of the trimmed test case
    */
-  void (*afl_custom_trim)(void *data, u8 **out_buf, size_t *out_buf_size);
+  size_t (*afl_custom_trim)(void *data, u8 **out_buf);
 
   /**
    * This method is called after each trim operation to inform you if your
@@ -693,9 +729,9 @@ struct custom_mutator {
    * @param data pointer returned in afl_custom_init for this fuzz case
    * @param success Indicates if the last trim operation was successful.
    * @return The next trim iteration index (from 0 to the maximum amount of
-   *     steps returned in init_trim)
+   *     steps returned in init_trim). Negative on error.
    */
-  u32 (*afl_custom_post_trim)(void *data, u8 success);
+  s32 (*afl_custom_post_trim)(void *data, u8 success);
 
   /**
    * Perform a single custom mutation on a given input.
@@ -703,16 +739,18 @@ struct custom_mutator {
    *
    * (Optional)
    *
-   * @param data pointer returned in afl_custom_init for this fuzz case
-   * @param[inout] buf Pointer to the input data to be mutated and the mutated
+   * @param[in] data pointer returned in afl_custom_init for this fuzz case
+   * @param[in] buf Pointer to the input data to be mutated and the mutated
    *     output
    * @param[in] buf_size Size of input data
+   * @param[out] out_buf The new buffer. It's legal to reuse *buf if it's <
+   * buf_size.
    * @param[in] max_size Maximum size of the mutated output. The mutation must
    *     not produce data larger than max_size.
-   * @return Size of the mutated output.
+   * @return Size of the mutated output (out_size).
    */
-  size_t (*afl_custom_havoc_mutation)(void *data, u8 **buf,
-                                      size_t buf_size, size_t max_size);
+  size_t (*afl_custom_havoc_mutation)(void *data, u8 *buf, size_t buf_size,
+                                      u8 **out_buf, size_t max_size);
 
   /**
    * Return the probability (in percentage) that afl_custom_havoc_mutation
@@ -748,9 +786,8 @@ struct custom_mutator {
    * @param filename_orig_queue File name of the original queue entry. This
    *     argument can be NULL while initializing the fuzzer
    */
-  void (*afl_custom_queue_new_entry)(void *data,
-                                     const u8 *   filename_new_queue,
-                                     const u8 *   filename_orig_queue);
+  void (*afl_custom_queue_new_entry)(void *data, const u8 *filename_new_queue,
+                                     const u8 *filename_orig_queue);
   /**
    * Deinitialize the custom mutator.
    *
@@ -777,10 +814,10 @@ u8   trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
 void finalize_py_module(void *);
 
 size_t pre_save_py(void *, u8 *, size_t, u8 **);
-u32    init_trim_py(void *, u8 *, size_t);
-u32    post_trim_py(void *, u8);
-void   trim_py(void *, u8 **, size_t *);
-size_t havoc_mutation_py(void *, u8 **, size_t, size_t);
+s32    init_trim_py(void *, u8 *, size_t);
+s32    post_trim_py(void *, u8);
+size_t trim_py(void *, u8 **);
+size_t havoc_mutation_py(void *, u8 *, size_t, u8 **, size_t);
 u8     havoc_mutation_probability_py(void *);
 u8     queue_get_py(void *, const u8 *);
 void   queue_new_entry_py(void *, const u8 *, const u8 *);
@@ -898,13 +935,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
 static inline u32 rand_below(afl_state_t *afl, u32 limit) {
 
 #ifdef HAVE_ARC4RANDOM
-  if (afl->fixed_seed) { return random() % limit; }
+  if (unlikely(afl->fixed_seed)) { return random() % limit; }
 
   /* The boundary not being necessarily a power of 2,
      we need to ensure the result uniformity. */
   return arc4random_uniform(limit);
 #else
-  if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) {
+  if (unlikely(!afl->rand_cnt--) && likely(!afl->fixed_seed)) {
 
     ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
             "/dev/urandom");
@@ -920,7 +957,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
 
 static inline u32 get_rand_seed(afl_state_t *afl) {
 
-  if (afl->fixed_seed) return (u32)afl->init_seed;
+  if (unlikely(afl->fixed_seed)) return (u32)afl->init_seed;
   return afl->rand_seed[0];
 
 }
@@ -928,7 +965,7 @@ static inline u32 get_rand_seed(afl_state_t *afl) {
 /* Find first power of two greater or equal to val (assuming val under
    2^63). */
 
-static u64 next_p2(u64 val) {
+static inline u64 next_p2(u64 val) {
 
   u64 ret = 1;
   while (val > ret)