aboutsummaryrefslogtreecommitdiff
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)