code-format

This commit is contained in:
van Hauser
2020-03-09 12:21:54 +01:00
parent 188a6f5ec5
commit 988a32ced5
25 changed files with 1014 additions and 802 deletions

View File

@ -109,8 +109,8 @@
extern s8 interesting_8[INTERESTING_8_LEN]; extern s8 interesting_8[INTERESTING_8_LEN];
extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN]; extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN];
extern s32 interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN]; extern s32
interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN];
struct queue_entry { struct queue_entry {
@ -263,7 +263,6 @@ extern u8 *doc_path; /* gath to documentation dir */
#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE #define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE
#endif #endif
enum { enum {
/* 00 */ PY_FUNC_INIT, /* 00 */ PY_FUNC_INIT,
@ -503,8 +502,7 @@ typedef struct afl_state {
*queue_top, /* Top of the list */ *queue_top, /* Top of the list */
*q_prev100; /* Previous 100 marker */ *q_prev100; /* Previous 100 marker */
struct queue_entry* struct queue_entry* top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
struct extra_data* extras; /* Extra tokens to fuzz with */ struct extra_data* extras; /* Extra tokens to fuzz with */
u32 extras_cnt; /* Total number of tokens read */ u32 extras_cnt; /* Total number of tokens read */
@ -525,7 +523,8 @@ typedef struct afl_state {
/* cmplog forkserver ids */ /* cmplog forkserver ids */
s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
u8 describe_op_buf_256[256]; /* describe_op will use this to return a string up to 256 */ u8 describe_op_buf_256[256]; /* describe_op will use this to return a string
up to 256 */
#ifdef USE_PYTHON #ifdef USE_PYTHON
/* Python Mutators */ /* Python Mutators */
@ -540,7 +539,8 @@ typedef struct afl_state {
} afl_state_t; } afl_state_t;
/* A global pointer to all instances is needed (for now) for signals to arrive */ /* A global pointer to all instances is needed (for now) for signals to arrive
*/
extern list_t afl_states; extern list_t afl_states;
@ -574,8 +574,8 @@ struct custom_mutator {
* not produce data larger than max_size. * not produce data larger than max_size.
* @return Size of the mutated output. * @return Size of the mutated output.
*/ */
size_t (*afl_custom_fuzz)(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf, size_t (*afl_custom_fuzz)(afl_state_t* afl, u8** buf, size_t buf_size,
size_t add_buf_size, size_t max_size); u8* add_buf, size_t add_buf_size, size_t max_size);
/** /**
* A post-processing function to use right before AFL writes the test case to * A post-processing function to use right before AFL writes the test case to
@ -591,7 +591,8 @@ struct custom_mutator {
* will release the memory after saving the test case. * will release the memory after saving the test case.
* @return Size of the output buffer after processing * @return Size of the output buffer after processing
*/ */
size_t (*afl_custom_pre_save)(afl_state_t *afl, u8* buf, size_t buf_size, u8** out_buf); size_t (*afl_custom_pre_save)(afl_state_t* afl, u8* buf, size_t buf_size,
u8** out_buf);
/** /**
* This method is called at the start of each trimming operation and receives * This method is called at the start of each trimming operation and receives
@ -659,7 +660,8 @@ struct custom_mutator {
* not produce data larger than max_size. * not produce data larger than max_size.
* @return Size of the mutated output. * @return Size of the mutated output.
*/ */
size_t (*afl_custom_havoc_mutation)(afl_state_t *afl, u8** buf, size_t buf_size, size_t max_size); size_t (*afl_custom_havoc_mutation)(afl_state_t* afl, u8** buf,
size_t buf_size, size_t max_size);
/** /**
* Return the probability (in percentage) that afl_custom_havoc_mutation * Return the probability (in percentage) that afl_custom_havoc_mutation
@ -692,13 +694,12 @@ struct custom_mutator {
* @param filename_orig_queue File name of the original queue entry. This * @param filename_orig_queue File name of the original queue entry. This
* argument can be NULL while initializing the fuzzer * argument can be NULL while initializing the fuzzer
*/ */
void (*afl_custom_queue_new_entry)(afl_state_t *afl, const u8* filename_new_queue, void (*afl_custom_queue_new_entry)(afl_state_t* afl,
const u8* filename_new_queue,
const u8* filename_orig_queue); const u8* filename_orig_queue);
}; };
void afl_state_init(afl_state_t*); void afl_state_init(afl_state_t*);
void afl_state_deinit(afl_state_t*); void afl_state_deinit(afl_state_t*);
@ -853,7 +854,8 @@ static inline u32 UR(afl_state_t *afl, u32 limit) {
#else #else
if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) { if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) {
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom"); ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
"/dev/urandom");
srandom(afl->rand_seed[0]); srandom(afl->rand_seed[0]);
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG); afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);

View File

@ -1,4 +1,5 @@
/* If we know we'll reuse small elements often, we'll just preallocate a buffer, then fall back to malloc */ /* If we know we'll reuse small elements often, we'll just preallocate a buffer,
* then fall back to malloc */
// TODO: Replace free status check with bitmask+CLZ // TODO: Replace free status check with bitmask+CLZ
#ifndef AFL_PREALLOC_H #ifndef AFL_PREALLOC_H
@ -11,26 +12,29 @@
#include "debug.h" #include "debug.h"
typedef enum prealloc_status { typedef enum prealloc_status {
PRE_STATUS_UNUSED = 0, /* free in buf */ PRE_STATUS_UNUSED = 0, /* free in buf */
PRE_STATUS_USED, /* used in buf */ PRE_STATUS_USED, /* used in buf */
PRE_STATUS_MALLOC /* system malloc */ PRE_STATUS_MALLOC /* system malloc */
} pre_status_t;
} pre_status_t;
/* Adds the entry used for prealloc bookkeeping to this struct */ /* Adds the entry used for prealloc bookkeeping to this struct */
#define PREALLOCABLE ;pre_status_t pre_status; /* prealloc status of this instance */ #define PREALLOCABLE \
; \
pre_status_t pre_status; /* prealloc status of this instance */
/* allocate an element of type *el_ptr, to this variable. /* allocate an element of type *el_ptr, to this variable.
Uses (and reuses) the given prealloc_buf before hitting libc's malloc. Uses (and reuses) the given prealloc_buf before hitting libc's malloc.
prealloc_buf must be the pointer to an array with type `type`. prealloc_buf must be the pointer to an array with type `type`.
`type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status member). `type` must be a struct with uses PREALLOCABLE (a pre_status_t pre_status
prealloc_size must be the array size. member). prealloc_size must be the array size. prealloc_counter must be a
prealloc_counter must be a variable initialized with 0 (of any name). variable initialized with 0 (of any name).
*/ */
#define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) do { \ #define PRE_ALLOC(el_ptr, prealloc_buf, prealloc_size, prealloc_counter) \
do { \
\ \
if ((prealloc_counter) >= (prealloc_size)) { \ if ((prealloc_counter) >= (prealloc_size)) { \
\ \
@ -51,51 +55,66 @@ typedef enum prealloc_status {
break; \ break; \
\ \
} \ } \
} \ \
} \ } \
\ \
if(!el_ptr) { \
FATAL("BUG in list.h -> no element found or allocated!"); \
} \ } \
\
if (!el_ptr) { FATAL("BUG in list.h -> no element found or allocated!"); } \
\
} while (0); } while (0);
/* Take a chosen (free) element from the prealloc_buf directly */ /* Take a chosen (free) element from the prealloc_buf directly */
#define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) do { \ #define PRE_ALLOC_FORCE(el_ptr, prealloc_counter) \
do { \
\
if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \ if ((el_ptr)->pre_status != PRE_STATUS_UNUSED) { \
\
FATAL("PRE_ALLOC_FORCE element already allocated"); \ FATAL("PRE_ALLOC_FORCE element already allocated"); \
\
} \ } \
(el_ptr)->pre_status = PRE_STATUS_USED; \ (el_ptr)->pre_status = PRE_STATUS_USED; \
(prealloc_counter)++; \ (prealloc_counter)++; \
\
} while (0); } while (0);
/* free an preallocated element */ /* free an preallocated element */
#define PRE_FREE(el_ptr, prealloc_counter) do { \ #define PRE_FREE(el_ptr, prealloc_counter) \
do { \
\ \
switch ((el_ptr)->pre_status) { \ switch ((el_ptr)->pre_status) { \
\ \
case PRE_STATUS_USED: { \ case PRE_STATUS_USED: { \
\
(el_ptr)->pre_status = PRE_STATUS_UNUSED; \ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
(prealloc_counter)--; \ (prealloc_counter)--; \
if ((prealloc_counter) < 0) { \ if ((prealloc_counter) < 0) { \
\
FATAL("Inconsistent data in PRE_FREE"); \ FATAL("Inconsistent data in PRE_FREE"); \
\
} \ } \
break; \ break; \
\
} \ } \
case PRE_STATUS_MALLOC: { \ case PRE_STATUS_MALLOC: { \
\
(el_ptr)->pre_status = PRE_STATUS_UNUSED; \ (el_ptr)->pre_status = PRE_STATUS_UNUSED; \
free((el_ptr)); \ free((el_ptr)); \
break; \ break; \
\
} \ } \
default: { \ default: { \
\
FATAL("Double Free Detected"); \ FATAL("Double Free Detected"); \
break; \ break; \
\
} \ } \
\ \
} \ } \
\
} while (0); } while (0);
#endif #endif

View File

@ -64,3 +64,4 @@ static u64 get_cur_time_us(void) {
} }
#endif #endif

View File

@ -61,8 +61,6 @@ s32 out_fd, /* Persistent fd for afl->fsrv.out_file *
} afl_forkserver_t; } afl_forkserver_t;
void handle_timeout(int sig); void handle_timeout(int sig);
void afl_fsrv_init(afl_forkserver_t *fsrv); void afl_fsrv_init(afl_forkserver_t *fsrv);
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv); void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv);

View File

@ -8,9 +8,11 @@
#include "debug.h" #include "debug.h"
#include "afl-prealloc.h" #include "afl-prealloc.h"
#define LIST_PREALLOC_SIZE (64) /* How many elements to allocate before malloc is needed */ #define LIST_PREALLOC_SIZE \
(64) /* How many elements to allocate before malloc is needed */
typedef struct list_element { typedef struct list_element {
PREALLOCABLE; PREALLOCABLE;
struct list_element *prev; struct list_element *prev;
@ -52,7 +54,8 @@ static void list_append(list_t *list, void *el) {
} }
element_t *el_box = NULL; element_t *el_box = NULL;
PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE, list->element_prealloc_count); PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE,
list->element_prealloc_count);
if (!el_box) FATAL("failed to allocate list element"); if (!el_box) FATAL("failed to allocate list element");
el_box->data = el; el_box->data = el;
el_box->next = head; el_box->next = head;
@ -68,36 +71,48 @@ static void list_append(list_t *list, void *el) {
A return from this block will return from calling func. A return from this block will return from calling func.
*/ */
#define LIST_FOREACH(list, type, block) do { \ #define LIST_FOREACH(list, type, block) \
do { \
\
list_t * li = (list); \ list_t * li = (list); \
element_t *head = get_head((li)); \ element_t *head = get_head((li)); \
element_t *el_box = (head)->next; \ element_t *el_box = (head)->next; \
if (!el_box) \ if (!el_box) FATAL("foreach over uninitialized list"); \
FATAL("foreach over uninitialized list");\
while (el_box != head) { \ while (el_box != head) { \
\
type *el = (type *)((el_box)->data); \ type *el = (type *)((el_box)->data); \
/* get next so el_box can be unlinked */ \ /* get next so el_box can be unlinked */ \
element_t *next = el_box->next; \ element_t *next = el_box->next; \
{block}; \ {block}; \
el_box = next; \ el_box = next; \
\
} \ } \
\
} while (0); } while (0);
/* In foreach: remove the current el from the list */ /* In foreach: remove the current el from the list */
#define LIST_REMOVE_CURRENT_EL_IN_FOREACH() do { \ #define LIST_REMOVE_CURRENT_EL_IN_FOREACH() \
do { \
\
el_box->prev->next = next; \ el_box->prev->next = next; \
el_box->next->prev = el_box->prev; \ el_box->next->prev = el_box->prev; \
list_free_el(li, el_box); \ list_free_el(li, el_box); \
\
} while (0); } while (0);
/* Same as foreach, but will clear list in the process */ /* Same as foreach, but will clear list in the process */
#define LIST_FOREACH_CLEAR(list, type, block) do { \ #define LIST_FOREACH_CLEAR(list, type, block) \
do { \
\
LIST_FOREACH((list), type, { \ LIST_FOREACH((list), type, { \
\
{block}; \ {block}; \
LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \ LIST_REMOVE_CURRENT_EL_IN_FOREACH(); \
\
}); \ }); \
\
} while (0); } while (0);
/* remove an item from the list */ /* remove an item from the list */
@ -105,13 +120,17 @@ static void list_append(list_t *list, void *el) {
static void list_remove(list_t *list, void *remove_me) { static void list_remove(list_t *list, void *remove_me) {
LIST_FOREACH(list, void, { LIST_FOREACH(list, void, {
if (el == remove_me) { if (el == remove_me) {
el_box->prev->next = el_box->next; el_box->prev->next = el_box->next;
el_box->next->prev = el_box->prev; el_box->next->prev = el_box->prev;
el_box->data = NULL; el_box->data = NULL;
list_free_el(list, el_box); list_free_el(list, el_box);
return; return;
} }
}); });
FATAL("List item to be removed not in list"); FATAL("List item to be removed not in list");
@ -123,7 +142,9 @@ static void list_remove(list_t *list, void *remove_me) {
static bool list_contains(list_t *list, void *contains_me) { static bool list_contains(list_t *list, void *contains_me) {
LIST_FOREACH(list, void, { LIST_FOREACH(list, void, {
if (el == contains_me) return true; if (el == contains_me) return true;
}); });
return false; return false;

View File

@ -1014,9 +1014,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &target_path, argc - optind, argv + optind); use_argv =
get_wine_argv(argv[0], &target_path, argc - optind, argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind); use_argv =
get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind);
} else } else

View File

@ -168,7 +168,8 @@ char** get_qemu_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the 'afl-qemu-trace' binary. The binary must be " "Oops, unable to find the 'afl-qemu-trace' binary. The binary must be "
"built\n" "built\n"
" separately by following the instructions in afl->qemu_mode/README.md. " " separately by following the instructions in "
"afl->qemu_mode/README.md. "
"If you\n" "If you\n"
" already have the binary installed, you may need to specify " " already have the binary installed, you may need to specify "
"AFL_PATH in the\n" "AFL_PATH in the\n"
@ -264,7 +265,8 @@ char** get_wine_argv(u8* own_loc, u8 **target_path_p, int argc, char **argv) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the '%s' binary. The binary must be " "Oops, unable to find the '%s' binary. The binary must be "
"built\n" "built\n"
" separately by following the instructions in afl->qemu_mode/README.md. " " separately by following the instructions in "
"afl->qemu_mode/README.md. "
"If you\n" "If you\n"
" already have the binary installed, you may need to specify " " already have the binary installed, you may need to specify "
"AFL_PATH in the\n" "AFL_PATH in the\n"
@ -329,3 +331,4 @@ char* get_afl_env(char* env) {
return val; return val;
} }

View File

@ -465,8 +465,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv) {
void afl_fsrv_killall() { void afl_fsrv_killall() {
LIST_FOREACH(&fsrv_list, afl_forkserver_t, { LIST_FOREACH(&fsrv_list, afl_forkserver_t, {
if (el->child_pid > 0) kill(el->child_pid, SIGKILL); if (el->child_pid > 0) kill(el->child_pid, SIGKILL);
}); });
} }
void afl_fsrv_deinit(afl_forkserver_t *fsrv) { void afl_fsrv_deinit(afl_forkserver_t *fsrv) {
@ -474,3 +477,4 @@ void afl_fsrv_deinit(afl_forkserver_t *fsrv) {
list_remove(&fsrv_list, fsrv); list_remove(&fsrv_list, fsrv);
} }

View File

@ -429,7 +429,8 @@ u8* describe_op(afl_state_t *afl, u8 hnb) {
sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time); sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
if (afl->splicing_with >= 0) sprintf(ret + strlen(ret), "+%06d", afl->splicing_with); if (afl->splicing_with >= 0)
sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
sprintf(ret + strlen(ret), ",op:%s", afl->stage_short); sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
@ -439,7 +440,8 @@ u8* describe_op(afl_state_t *afl, u8 hnb) {
if (afl->stage_val_type != STAGE_VAL_NONE) if (afl->stage_val_type != STAGE_VAL_NONE)
sprintf(ret + strlen(ret), ",val:%s%+d", sprintf(ret + strlen(ret), ",val:%s%+d",
(afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "", afl->stage_cur_val); (afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "",
afl->stage_cur_val);
} else } else
@ -634,8 +636,8 @@ u8 save_if_interesting(afl_state_t *afl, void* mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES #ifndef SIMPLE_FILES
fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir, afl->unique_hangs, fn = alloc_printf("%s/hangs/id:%06llu,%s", afl->out_dir,
describe_op(afl, 0)); afl->unique_hangs, describe_op(afl, 0));
#else #else
@ -678,17 +680,19 @@ u8 save_if_interesting(afl_state_t *afl, void* mem, u32 len, u8 fault) {
#ifndef SIMPLE_FILES #ifndef SIMPLE_FILES
fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, fn = alloc_printf("%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir,
afl->unique_crashes, afl->kill_signal, describe_op(afl, 0)); afl->unique_crashes, afl->kill_signal,
describe_op(afl, 0));
#else #else
fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir, afl->unique_crashes, fn = alloc_printf("%s/crashes/id_%06llu_%02u", afl->out_dir,
afl->kill_signal); afl->unique_crashes, afl->kill_signal);
#endif /* ^!SIMPLE_FILES */ #endif /* ^!SIMPLE_FILES */
++afl->unique_crashes; ++afl->unique_crashes;
if (afl->infoexec) { // if the user wants to be informed on new crashes - do if (afl->infoexec) { // if the user wants to be informed on new crashes -
// do
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
// that // that
if (system(afl->infoexec) == -1) if (system(afl->infoexec) == -1)

View File

@ -81,8 +81,9 @@ void init_cmplog_forkserver(afl_state_t *afl) {
// r.rlim_max = r.rlim_cur = 0; // r.rlim_max = r.rlim_cur = 0;
// setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ // setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -176,7 +177,8 @@ void init_cmplog_forkserver(afl_state_t *afl) {
if (afl->fsrv.exec_tmout) { if (afl->fsrv.exec_tmout) {
it.it_value.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000); it.it_value.tv_sec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) / 1000);
it.it_value.tv_usec = ((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000; it.it_value.tv_usec =
((afl->fsrv.exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;
} }
@ -204,11 +206,13 @@ void init_cmplog_forkserver(afl_state_t *afl) {
"Timeout while initializing cmplog fork server (adjusting -t may " "Timeout while initializing cmplog fork server (adjusting -t may "
"help)"); "help)");
if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->cmplog_fsrv_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
if (WIFSIGNALED(status)) { if (WIFSIGNALED(status)) {
if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 && afl->fsrv.uses_asan) { if (afl->fsrv.mem_limit && afl->fsrv.mem_limit < 500 &&
afl->fsrv.uses_asan) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, " "Whoops, the target binary crashed suddenly, "
@ -400,8 +404,9 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -495,7 +500,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
if (afl->dumb_mode == 1 || afl->no_forkserver) { if (afl->dumb_mode == 1 || afl->no_forkserver) {
if (waitpid(afl->cmplog_child_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->cmplog_child_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
} else { } else {
@ -540,8 +546,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
++afl->total_execs; ++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
compiler below this point. Past this location, afl->fsrv.trace_bits[] behave compiler below this point. Past this location, afl->fsrv.trace_bits[]
very normally and do not have to be treated as volatile. */ behave very normally and do not have to be treated as volatile. */
MEM_BARRIER(); MEM_BARRIER();
@ -561,7 +567,8 @@ u8 run_cmplog_target(afl_state_t *afl, u32 timeout) {
afl->kill_signal = WTERMSIG(status); afl->kill_signal = WTERMSIG(status);
if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL) return FAULT_TMOUT; if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL)
return FAULT_TMOUT;
return FAULT_CRASH; return FAULT_CRASH;
@ -627,10 +634,11 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8* out_buf, u32 len) {
/* This handles FAULT_ERROR for us: */ /* This handles FAULT_ERROR for us: */
/* afl->queued_discovered += save_if_interesting(afl, argv, out_buf, len, fault); /* afl->queued_discovered += save_if_interesting(afl, argv, out_buf, len,
fault);
if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 == afl->stage_max) if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 ==
show_stats(afl); */ afl->stage_max) show_stats(afl); */
return 0; return 0;

View File

@ -45,7 +45,8 @@ static int compare_extras_use_d(const void* p1, const void* p2) {
/* Read extras from a file, sort by size. */ /* Read extras from a file, sort by size. */
void load_extras_file(afl_state_t *afl, u8* fname, u32* min_len, u32* max_len, u32 dict_level) { void load_extras_file(afl_state_t* afl, u8* fname, u32* min_len, u32* max_len,
u32 dict_level) {
FILE* f; FILE* f;
u8 buf[MAX_LINE]; u8 buf[MAX_LINE];
@ -120,8 +121,8 @@ void load_extras_file(afl_state_t *afl, u8* fname, u32* min_len, u32* max_len, u
/* Okay, let's allocate memory and copy data between "...", handling /* Okay, let's allocate memory and copy data between "...", handling
\xNN escaping, \\, and \". */ \xNN escaping, \\, and \". */
afl->extras = afl->extras = ck_realloc_block(
ck_realloc_block(afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr); wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
@ -241,8 +242,8 @@ void load_extras(afl_state_t *afl, u8* dir) {
if (min_len > st.st_size) min_len = st.st_size; if (min_len > st.st_size) min_len = st.st_size;
if (max_len < st.st_size) max_len = st.st_size; if (max_len < st.st_size) max_len = st.st_size;
afl->extras = afl->extras = ck_realloc_block(
ck_realloc_block(afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data)); afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size); afl->extras[afl->extras_cnt].data = ck_alloc(st.st_size);
afl->extras[afl->extras_cnt].len = st.st_size; afl->extras[afl->extras_cnt].len = st.st_size;
@ -266,10 +267,11 @@ check_and_sort:
if (!afl->extras_cnt) FATAL("No usable files in '%s'", dir); if (!afl->extras_cnt) FATAL("No usable files in '%s'", dir);
qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data), compare_extras_len); qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
compare_extras_len);
OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt, DMS(min_len), OKF("Loaded %u extra tokens, size range %s to %s.", afl->extras_cnt,
DMS(max_len)); DMS(min_len), DMS(max_len));
if (max_len > 32) if (max_len > 32)
WARNF("Some tokens are relatively large (%s) - consider trimming.", WARNF("Some tokens are relatively large (%s) - consider trimming.",
@ -349,7 +351,8 @@ void maybe_add_auto(afl_state_t *afl, u8* mem, u32 len) {
for (i = 0; i < afl->a_extras_cnt; ++i) { for (i = 0; i < afl->a_extras_cnt; ++i) {
if (afl->a_extras[i].len == len && !memcmp_nocase(afl->a_extras[i].data, mem, len)) { if (afl->a_extras[i].len == len &&
!memcmp_nocase(afl->a_extras[i].data, mem, len)) {
afl->a_extras[i].hit_cnt++; afl->a_extras[i].hit_cnt++;
goto sort_a_extras; goto sort_a_extras;
@ -364,8 +367,8 @@ void maybe_add_auto(afl_state_t *afl, u8* mem, u32 len) {
if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) { if (afl->a_extras_cnt < MAX_AUTO_EXTRAS) {
afl->a_extras = ck_realloc_block(afl->a_extras, afl->a_extras = ck_realloc_block(
(afl->a_extras_cnt + 1) * sizeof(struct extra_data)); afl->a_extras, (afl->a_extras_cnt + 1) * sizeof(struct extra_data));
afl->a_extras[afl->a_extras_cnt].data = ck_memdup(mem, len); afl->a_extras[afl->a_extras_cnt].data = ck_memdup(mem, len);
afl->a_extras[afl->a_extras_cnt].len = len; afl->a_extras[afl->a_extras_cnt].len = len;
@ -392,8 +395,8 @@ sort_a_extras:
/* Then, sort the top USE_AUTO_EXTRAS entries by size. */ /* Then, sort the top USE_AUTO_EXTRAS entries by size. */
qsort(afl->a_extras, MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt), sizeof(struct extra_data), qsort(afl->a_extras, MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt),
compare_extras_len); sizeof(struct extra_data), compare_extras_len);
} }
@ -408,7 +411,8 @@ void save_auto(afl_state_t *afl) {
for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) { for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
u8* fn = alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i); u8* fn =
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
s32 fd; s32 fd;
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600); fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);

View File

@ -68,7 +68,8 @@ static void init_mopt_globals(afl_state_t *afl){
} }
/* A global pointer to all instances is needed (for now) for signals to arrive */ /* A global pointer to all instances is needed (for now) for signals to arrive
*/
list_t afl_states = {0}; list_t afl_states = {0};

View File

@ -368,8 +368,8 @@ void read_testcases(afl_state_t *afl) {
struct stat st; struct stat st;
u8* fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name); u8* fn2 = alloc_printf("%s/%s", afl->in_dir, nl[i]->d_name);
u8* dfn = u8* dfn = alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir,
alloc_printf("%s/.state/deterministic_done/%s", afl->in_dir, nl[i]->d_name); nl[i]->d_name);
u8 passed_det = 0; u8 passed_det = 0;
@ -493,9 +493,9 @@ void perform_dry_run(afl_state_t *afl) {
if (afl->timeout_given) { if (afl->timeout_given) {
/* The -t nn+ syntax in the command line sets afl->timeout_given to '2' and /* The -t nn+ syntax in the command line sets afl->timeout_given to
instructs afl-fuzz to tolerate but skip queue entries that time '2' and instructs afl-fuzz to tolerate but skip queue entries that
out. */ time out. */
if (afl->timeout_given > 1) { if (afl->timeout_given > 1) {
@ -593,7 +593,8 @@ void perform_dry_run(afl_state_t *afl) {
"other options\n" "other options\n"
" fail, poke <afl-users@googlegroups.com> for " " fail, poke <afl-users@googlegroups.com> for "
"troubleshooting tips.\n", "troubleshooting tips.\n",
DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1, doc_path); DMS(afl->fsrv.mem_limit << 20), afl->fsrv.mem_limit - 1,
doc_path);
} else { } else {
@ -1048,7 +1049,8 @@ static void handle_existing_out_dir(afl_state_t *afl) {
/* Let's see how much work is at stake. */ /* Let's see how much work is at stake. */
if (!afl->in_place_resume && last_update - start_time2 > OUTPUT_GRACE * 60) { if (!afl->in_place_resume &&
last_update - start_time2 > OUTPUT_GRACE * 60) {
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"The job output directory already exists and contains the results " "The job output directory already exists and contains the results "
@ -1140,7 +1142,8 @@ static void handle_existing_out_dir(afl_state_t *afl) {
if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;
ck_free(fn); ck_free(fn);
/* All right, let's do <afl->out_dir>/crashes/id:* and <afl->out_dir>/hangs/id:*. */ /* All right, let's do <afl->out_dir>/crashes/id:* and
* <afl->out_dir>/hangs/id:*. */
if (!afl->in_place_resume) { if (!afl->in_place_resume) {
@ -1300,7 +1303,8 @@ void setup_dirs_fds(afl_state_t *afl) {
#ifndef __sun #ifndef __sun
if (afl->fsrv.out_dir_fd < 0 || flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB)) if (afl->fsrv.out_dir_fd < 0 ||
flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB))
PFATAL("Unable to flock() output directory."); PFATAL("Unable to flock() output directory.");
#endif /* !__sun */ #endif /* !__sun */
@ -1537,8 +1541,8 @@ void check_cpu_governor(afl_state_t *afl) {
if (get_afl_env("AFL_SKIP_CPUFREQ")) return; if (get_afl_env("AFL_SKIP_CPUFREQ")) return;
if (afl->cpu_aff > 0) if (afl->cpu_aff > 0)
snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpu", afl->cpu_aff, snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpu",
"/cpufreq/scaling_governor"); afl->cpu_aff, "/cpufreq/scaling_governor");
else else
snprintf(tmp, sizeof(tmp), "%s", snprintf(tmp, sizeof(tmp), "%s",
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
@ -1661,7 +1665,8 @@ void get_core_count(afl_state_t *afl) {
#ifdef __APPLE__ #ifdef __APPLE__
if (sysctlbyname("hw.logicalcpu", &afl->cpu_core_count, &s, NULL, 0) < 0) return; if (sysctlbyname("hw.logicalcpu", &afl->cpu_core_count, &s, NULL, 0) < 0)
return;
#else #else
@ -1896,7 +1901,8 @@ void check_binary(afl_state_t *afl, u8* fname) {
} }
if (!afl->fsrv.target_path) FATAL("Program '%s' not found or not executable", fname); if (!afl->fsrv.target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -1904,8 +1910,10 @@ void check_binary(afl_state_t *afl, u8* fname) {
/* Check for blatant user errors. */ /* Check for blatant user errors. */
if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) && !strchr(afl->fsrv.target_path + 5, '/')) || if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) &&
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) && !strchr(afl->fsrv.target_path + 9, '/'))) !strchr(afl->fsrv.target_path + 5, '/')) ||
(!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) &&
!strchr(afl->fsrv.target_path + 9, '/')))
FATAL("Please don't keep binaries in /tmp or /var/tmp"); FATAL("Please don't keep binaries in /tmp or /var/tmp");
fd = open(afl->fsrv.target_path, O_RDONLY); fd = open(afl->fsrv.target_path, O_RDONLY);
@ -1914,7 +1922,8 @@ void check_binary(afl_state_t *afl, u8* fname) {
f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0); f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
if (f_data == MAP_FAILED) PFATAL("Unable to mmap file '%s'", afl->fsrv.target_path); if (f_data == MAP_FAILED)
PFATAL("Unable to mmap file '%s'", afl->fsrv.target_path);
close(fd); close(fd);

View File

@ -36,6 +36,7 @@ void setup_custom_mutator(afl_state_t *afl) {
u8* fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); u8* fn = getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
if (fn) { if (fn) {
if (afl->limit_time_sig) if (afl->limit_time_sig)
FATAL( FATAL(
"MOpt and custom mutator are mutually exclusive. We accept pull " "MOpt and custom mutator are mutually exclusive. We accept pull "
@ -90,6 +91,7 @@ void destroy_custom_mutator(afl_state_t *afl) {
} }
ck_free(afl->mutator); ck_free(afl->mutator);
} }
} }
@ -109,7 +111,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* Mutator */ /* Mutator */
/* "afl_custom_init", optional for backward compatibility */ /* "afl_custom_init", optional for backward compatibility */
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init"); afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
if (!afl->mutator->afl_custom_init) WARNF("Symbol 'afl_custom_init' not found."); if (!afl->mutator->afl_custom_init)
WARNF("Symbol 'afl_custom_init' not found.");
/* "afl_custom_fuzz" or "afl_custom_mutator", required */ /* "afl_custom_fuzz" or "afl_custom_mutator", required */
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz"); afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
@ -137,7 +140,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
/* "afl_custom_trim", optional */ /* "afl_custom_trim", optional */
afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim"); afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
if (!afl->mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found."); if (!afl->mutator->afl_custom_trim)
WARNF("Symbol 'afl_custom_trim' not found.");
/* "afl_custom_post_trim", optional */ /* "afl_custom_post_trim", optional */
afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim"); afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
@ -156,7 +160,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
} }
/* "afl_custom_havoc_mutation", optional */ /* "afl_custom_havoc_mutation", optional */
afl->mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation"); afl->mutator->afl_custom_havoc_mutation =
dlsym(dh, "afl_custom_havoc_mutation");
if (!afl->mutator->afl_custom_havoc_mutation) if (!afl->mutator->afl_custom_havoc_mutation)
WARNF("Symbol 'afl_custom_havoc_mutation' not found."); WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
@ -172,7 +177,8 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
WARNF("Symbol 'afl_custom_queue_get' not found."); WARNF("Symbol 'afl_custom_queue_get' not found.");
/* "afl_custom_queue_new_entry", optional */ /* "afl_custom_queue_new_entry", optional */
afl->mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry"); afl->mutator->afl_custom_queue_new_entry =
dlsym(dh, "afl_custom_queue_new_entry");
if (!afl->mutator->afl_custom_queue_new_entry) if (!afl->mutator->afl_custom_queue_new_entry)
WARNF("Symbol 'afl_custom_queue_new_entry' not found"); WARNF("Symbol 'afl_custom_queue_new_entry' not found");
@ -315,8 +321,7 @@ void load_custom_mutator_py(afl_state_t *afl, const char* module_name) {
afl->mutator->name = module_name; afl->mutator->name = module_name;
ACTF("Loading Python mutator library from '%s'...", module_name); ACTF("Loading Python mutator library from '%s'...", module_name);
if (py_functions[PY_FUNC_INIT]) if (py_functions[PY_FUNC_INIT]) afl->mutator->afl_custom_init = init_py;
afl->mutator->afl_custom_init = init_py;
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
is quite different from the custom mutator. */ is quite different from the custom mutator. */
@ -331,8 +336,7 @@ void load_custom_mutator_py(afl_state_t *afl, const char* module_name) {
if (py_functions[PY_FUNC_POST_TRIM]) if (py_functions[PY_FUNC_POST_TRIM])
afl->mutator->afl_custom_post_trim = post_trim_py; afl->mutator->afl_custom_post_trim = post_trim_py;
if (py_functions[PY_FUNC_TRIM]) if (py_functions[PY_FUNC_TRIM]) afl->mutator->afl_custom_trim = trim_py;
afl->mutator->afl_custom_trim = trim_py;
if (py_functions[PY_FUNC_HAVOC_MUTATION]) if (py_functions[PY_FUNC_HAVOC_MUTATION])
afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py; afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;

View File

@ -52,7 +52,8 @@ int select_algorithm(afl_state_t *afl) {
} }
if (j_puppet == 1 && sele < afl->probability_now[afl->swarm_now][i_puppet - 1]) if (j_puppet == 1 &&
sele < afl->probability_now[afl->swarm_now][i_puppet - 1])
FATAL("error select_algorithm"); FATAL("error select_algorithm");
return i_puppet; return i_puppet;
@ -375,7 +376,9 @@ u8 fuzz_one_original(afl_state_t *afl) {
UR(afl, 100) < SKIP_TO_NEW_PROB) UR(afl, 100) < SKIP_TO_NEW_PROB)
return 1; return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored && afl->queued_paths > 10) { } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
/* Otherwise, still possibly skip non-favored cases, albeit less often. /* Otherwise, still possibly skip non-favored cases, albeit less often.
The odds of skipping stuff are higher for already-fuzzed inputs and The odds of skipping stuff are higher for already-fuzzed inputs and
@ -439,7 +442,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
if (res == FAULT_ERROR) FATAL("Unable to execute target application"); if (res == FAULT_ERROR) FATAL("Unable to execute target application");
@ -493,7 +497,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->shm.cmplog_mode) { if (afl->shm.cmplog_mode) {
if (input_to_state_stage(afl, in_buf, out_buf, len, afl->queue_cur->exec_cksum)) if (input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum))
goto abandon_entry; goto abandon_entry;
} }
@ -517,7 +522,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* Skip deterministic fuzzing if exec path checksum puts this out of scope /* Skip deterministic fuzzing if exec path checksum puts this out of scope
for this master instance. */ for this master instance. */
if (afl->master_max && (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) { if (afl->master_max &&
(afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) {
goto custom_mutator_stage; goto custom_mutator_stage;
@ -596,7 +602,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
/* If at end of file and we are still collecting a string, grab the /* If at end of file and we are still collecting a string, grab the
final character and force output. */ final character and force output. */
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)
@ -620,7 +627,8 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (cksum != afl->queue_cur->exec_cksum) { if (cksum != afl->queue_cur->exec_cksum) {
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
} }
@ -1392,10 +1400,12 @@ skip_interest:
is redundant, or if its entire span has no bytes set in the effector is redundant, or if its entire span has no bytes set in the effector
map. */ map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS && UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || if ((afl->extras_cnt > MAX_DET_EXTRAS &&
UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i || afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->extras[j].len))) { !memchr(eff_map + EFF_APOS(i), 1,
EFF_SPAN_ALEN(i, afl->extras[j].len))) {
--afl->stage_max; --afl->stage_max;
continue; continue;
@ -1598,9 +1608,8 @@ custom_mutator_stage:
ck_read(fd, new_buf, target->len, target->fname); ck_read(fd, new_buf, target->len, target->fname);
close(fd); close(fd);
size_t mutated_size = afl->mutator->afl_custom_fuzz(afl, &out_buf, len, size_t mutated_size = afl->mutator->afl_custom_fuzz(
new_buf, target->len, afl, &out_buf, len, new_buf, target->len, max_seed_size);
max_seed_size);
ck_free(new_buf); ck_free(new_buf);
@ -1663,8 +1672,8 @@ havoc_stage:
afl->stage_name = "havoc"; afl->stage_name = "havoc";
afl->stage_short = "havoc"; afl->stage_short = "havoc";
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * perf_score / afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
afl->havoc_div / 100; perf_score / afl->havoc_div / 100;
} else { } else {
@ -1690,7 +1699,8 @@ havoc_stage:
if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) { if (stacked_custom && afl->mutator->afl_custom_havoc_mutation_probability) {
stacked_custom_prob = afl->mutator->afl_custom_havoc_mutation_probability(afl); stacked_custom_prob =
afl->mutator->afl_custom_havoc_mutation_probability(afl);
if (stacked_custom_prob > 100) if (stacked_custom_prob > 100)
FATAL( FATAL(
"The probability returned by afl_custom_havoc_mutation_propability " "The probability returned by afl_custom_havoc_mutation_propability "
@ -1711,8 +1721,8 @@ havoc_stage:
if (stacked_custom && UR(afl, 100) < stacked_custom_prob) { if (stacked_custom && UR(afl, 100) < stacked_custom_prob) {
temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf, temp_len, temp_len = afl->mutator->afl_custom_havoc_mutation(afl, &out_buf,
MAX_FILE); temp_len, MAX_FILE);
} }
@ -1729,7 +1739,8 @@ havoc_stage:
/* Set byte to interesting value. */ /* Set byte to interesting value. */
out_buf[UR(afl, temp_len)] = interesting_8[UR(afl, sizeof(interesting_8))]; out_buf[UR(afl, temp_len)] =
interesting_8[UR(afl, sizeof(interesting_8))];
break; break;
case 2: case 2:
@ -1952,7 +1963,8 @@ havoc_stage:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else else
memset(new_buf + clone_to, memset(new_buf + clone_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], clone_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
clone_len);
/* Tail */ /* Tail */
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@ -1987,7 +1999,8 @@ havoc_stage:
} else } else
memset(out_buf + copy_to, UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], memset(out_buf + copy_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
copy_len); copy_len);
break; break;
@ -2013,7 +2026,8 @@ havoc_stage:
if (extra_len > temp_len) break; if (extra_len > temp_len) break;
insert_at = UR(afl, temp_len - extra_len + 1); insert_at = UR(afl, temp_len - extra_len + 1);
memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len); memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
} else { } else {
@ -2055,7 +2069,8 @@ havoc_stage:
memcpy(new_buf, out_buf, insert_at); memcpy(new_buf, out_buf, insert_at);
/* Inserted part */ /* Inserted part */
memcpy(new_buf + insert_at, afl->a_extras[use_extra].data, extra_len); memcpy(new_buf + insert_at, afl->a_extras[use_extra].data,
extra_len);
} else { } else {
@ -2144,8 +2159,8 @@ havoc_stage:
retry_splicing: retry_splicing:
if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES && afl->queued_paths > 1 && if (afl->use_splicing && splice_cycle++ < SPLICE_CYCLES &&
afl->queue_cur->len > 1) { afl->queued_paths > 1 && afl->queue_cur->len > 1) {
struct queue_entry* target; struct queue_entry* target;
u32 tid, split_at; u32 tid, split_at;
@ -2252,7 +2267,8 @@ radamsa_stage:
afl->stage_name = "radamsa"; afl->stage_name = "radamsa";
afl->stage_short = "radamsa"; afl->stage_short = "radamsa";
afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100) << afl->use_radamsa; afl->stage_max = (HAVOC_CYCLES * perf_score / afl->havoc_div / 100)
<< afl->use_radamsa;
if (afl->stage_max < HAVOC_MIN) afl->stage_max = HAVOC_MIN; if (afl->stage_max < HAVOC_MIN) afl->stage_max = HAVOC_MIN;
@ -2268,8 +2284,8 @@ radamsa_stage:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 new_len = u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len, get_rand_seed(afl)); get_rand_seed(afl));
if (new_len) { if (new_len) {
@ -2378,7 +2394,9 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
UR(afl, 100) < SKIP_TO_NEW_PROB) UR(afl, 100) < SKIP_TO_NEW_PROB)
return 1; return 1;
} else if (!afl->dumb_mode && !afl->queue_cur->favored && afl->queued_paths > 10) { } else if (!afl->dumb_mode && !afl->queue_cur->favored &&
afl->queued_paths > 10) {
/* Otherwise, still possibly skip non-favored cases, albeit less often. /* Otherwise, still possibly skip non-favored cases, albeit less often.
The odds of skipping stuff are higher for already-fuzzed inputs and The odds of skipping stuff are higher for already-fuzzed inputs and
@ -2416,7 +2434,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (orig_in == MAP_FAILED) PFATAL("Unable to mmap '%s'", afl->queue_cur->fname); if (orig_in == MAP_FAILED)
PFATAL("Unable to mmap '%s'", afl->queue_cur->fname);
close(fd); close(fd);
@ -2440,7 +2459,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (afl->queue_cur->cal_failed < CAL_CHANCES) { if (afl->queue_cur->cal_failed < CAL_CHANCES) {
res = calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0); res =
calibrate_case(afl, afl->queue_cur, in_buf, afl->queue_cycle - 1, 0);
if (res == FAULT_ERROR) FATAL("Unable to execute target application"); if (res == FAULT_ERROR) FATAL("Unable to execute target application");
@ -2492,17 +2512,20 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
this entry ourselves (was_fuzzed), or if it has gone through deterministic this entry ourselves (was_fuzzed), or if it has gone through deterministic
testing in earlier, resumed runs (passed_det). */ testing in earlier, resumed runs (passed_det). */
if (afl->skip_deterministic || afl->queue_cur->was_fuzzed || afl->queue_cur->passed_det) if (afl->skip_deterministic || afl->queue_cur->was_fuzzed ||
afl->queue_cur->passed_det)
goto havoc_stage; goto havoc_stage;
/* Skip deterministic fuzzing if exec path checksum puts this out of scope /* Skip deterministic fuzzing if exec path checksum puts this out of scope
for this master instance. */ for this master instance. */
if (afl->master_max && (afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1) if (afl->master_max &&
(afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1)
goto havoc_stage; goto havoc_stage;
cur_ms_lv = get_cur_time(); cur_ms_lv = get_cur_time();
if (!(afl->key_puppet == 0 && ((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) || if (!(afl->key_puppet == 0 &&
((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) ||
(afl->last_crash_time != 0 && (afl->last_crash_time != 0 &&
cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) || cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) ||
afl->last_path_time == 0))) { afl->last_path_time == 0))) {
@ -2585,7 +2608,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
/* If at end of file and we are still collecting a string, grab the /* If at end of file and we are still collecting a string, grab the
final character and force output. */ final character and force output. */
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA) if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)
@ -2609,7 +2633,8 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
if (cksum != afl->queue_cur->exec_cksum) { if (cksum != afl->queue_cur->exec_cksum) {
if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[afl->stage_cur >> 3]; if (a_len < MAX_AUTO_EXTRA)
a_collect[a_len] = out_buf[afl->stage_cur >> 3];
++a_len; ++a_len;
} }
@ -3381,10 +3406,12 @@ skip_interest:
is redundant, or if its entire span has no bytes set in the effector is redundant, or if its entire span has no bytes set in the effector
map. */ map. */
if ((afl->extras_cnt > MAX_DET_EXTRAS && UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) || if ((afl->extras_cnt > MAX_DET_EXTRAS &&
UR(afl, afl->extras_cnt) >= MAX_DET_EXTRAS) ||
afl->extras[j].len > len - i || afl->extras[j].len > len - i ||
!memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) || !memcmp(afl->extras[j].data, out_buf + i, afl->extras[j].len) ||
!memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, afl->extras[j].len))) { !memchr(eff_map + EFF_APOS(i), 1,
EFF_SPAN_ALEN(i, afl->extras[j].len))) {
--afl->stage_max; --afl->stage_max;
continue; continue;
@ -3539,14 +3566,15 @@ pacemaker_fuzzing:
afl->stage_name = MOpt_globals.havoc_stagename; afl->stage_name = MOpt_globals.havoc_stagename;
afl->stage_short = MOpt_globals.havoc_stagenameshort; afl->stage_short = MOpt_globals.havoc_stagenameshort;
afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * perf_score / afl->stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
afl->havoc_div / 100; perf_score / afl->havoc_div / 100;
} else { } else {
perf_score = orig_perf; perf_score = orig_perf;
snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat, splice_cycle); snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
splice_cycle);
afl->stage_name = afl->stage_name_buf64; afl->stage_name = afl->stage_name_buf64;
afl->stage_short = MOpt_globals.splice_stagenameshort; afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@ -3595,7 +3623,8 @@ pacemaker_fuzzing:
} else { } else {
perf_score = orig_perf; perf_score = orig_perf;
snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat, splice_cycle); snprintf(afl->stage_name_buf64, 64, MOpt_globals.splice_stageformat,
splice_cycle);
afl->stage_name = afl->stage_name_buf64; afl->stage_name = afl->stage_name_buf64;
afl->stage_short = MOpt_globals.splice_stagenameshort; afl->stage_short = MOpt_globals.splice_stagenameshort;
afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100; afl->stage_max = SPLICE_HAVOC * perf_score / afl->havoc_div / 100;
@ -3610,7 +3639,8 @@ pacemaker_fuzzing:
havoc_queued = afl->queued_paths; havoc_queued = afl->queued_paths;
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
++afl->stage_cur) {
u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2)); u32 use_stacking = 1 << (1 + UR(afl, HAVOC_STACK_POW2));
@ -3748,7 +3778,8 @@ pacemaker_fuzzing:
case 9: case 9:
/* Set byte to interesting value. */ /* Set byte to interesting value. */
if (temp_len < 4) break; if (temp_len < 4) break;
out_buf[UR(afl, temp_len)] = interesting_8[UR(afl, sizeof(interesting_8))]; out_buf[UR(afl, temp_len)] =
interesting_8[UR(afl, sizeof(interesting_8))];
MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1; MOpt_globals.cycles_v2[STAGE_INTEREST8] += 1;
break; break;
@ -3762,8 +3793,8 @@ pacemaker_fuzzing:
} else { } else {
*(u16*)(out_buf + UR(afl, temp_len - 1)) = *(u16*)(out_buf + UR(afl, temp_len - 1)) = SWAP16(
SWAP16(interesting_16[UR(afl, sizeof(interesting_16) >> 1)]); interesting_16[UR(afl, sizeof(interesting_16) >> 1)]);
} }
@ -3782,8 +3813,8 @@ pacemaker_fuzzing:
} else { } else {
*(u32*)(out_buf + UR(afl, temp_len - 3)) = *(u32*)(out_buf + UR(afl, temp_len - 3)) = SWAP32(
SWAP32(interesting_32[UR(afl, sizeof(interesting_32) >> 2)]); interesting_32[UR(afl, sizeof(interesting_32) >> 2)]);
} }
@ -3862,7 +3893,8 @@ pacemaker_fuzzing:
memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
else else
memset(new_buf + clone_to, memset(new_buf + clone_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], clone_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
clone_len);
/* Tail */ /* Tail */
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@ -3899,7 +3931,8 @@ pacemaker_fuzzing:
} else } else
memset(out_buf + copy_to, memset(out_buf + copy_to,
UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)], copy_len); UR(afl, 2) ? UR(afl, 256) : out_buf[UR(afl, temp_len)],
copy_len);
MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1; MOpt_globals.cycles_v2[STAGE_OverWrite75] += 1;
break; break;
@ -3939,7 +3972,8 @@ pacemaker_fuzzing:
} }
if (unlikely(afl->queued_paths + afl->unique_crashes > temp_total_found)) { if (unlikely(afl->queued_paths + afl->unique_crashes >
temp_total_found)) {
u64 temp_temp_puppet = u64 temp_temp_puppet =
afl->queued_paths + afl->unique_crashes - temp_total_found; afl->queued_paths + afl->unique_crashes - temp_total_found;
@ -3953,7 +3987,9 @@ pacemaker_fuzzing:
} /* if */ } /* if */
} /* for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) { */ } /* for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max;
++afl->stage_cur) { */
new_hit_cnt = afl->queued_paths + afl->unique_crashes; new_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -4089,10 +4125,11 @@ pacemaker_fuzzing:
afl->splicing_with = -1; afl->splicing_with = -1;
/* Update afl->pending_not_fuzzed count if we made it through the calibration /* Update afl->pending_not_fuzzed count if we made it through the
cycle and have not seen this entry before. */ calibration cycle and have not seen this entry before. */
// if (!afl->stop_soon && !afl->queue_cur->cal_failed && !afl->queue_cur->was_fuzzed) { // if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
// !afl->queue_cur->was_fuzzed) {
// afl->queue_cur->was_fuzzed = 1; // afl->queue_cur->was_fuzzed = 1;
// --afl->pending_not_fuzzed; // --afl->pending_not_fuzzed;
@ -4107,7 +4144,8 @@ pacemaker_fuzzing:
if (afl->key_puppet == 1) { if (afl->key_puppet == 1) {
if (unlikely(afl->queued_paths + afl->unique_crashes > if (unlikely(
afl->queued_paths + afl->unique_crashes >
((afl->queued_paths + afl->unique_crashes) * limit_time_bound + ((afl->queued_paths + afl->unique_crashes) * limit_time_bound +
afl->orig_hit_cnt_puppet))) { afl->orig_hit_cnt_puppet))) {
@ -4175,7 +4213,8 @@ pacemaker_fuzzing:
afl->core_operator_cycles_puppet[i]; afl->core_operator_cycles_puppet[i];
afl->core_operator_cycles_puppet_v3[i] = afl->core_operator_cycles_puppet_v3[i] =
afl->core_operator_cycles_puppet[i]; afl->core_operator_cycles_puppet[i];
afl->core_operator_finds_puppet_v2[i] = afl->core_operator_finds_puppet[i]; afl->core_operator_finds_puppet_v2[i] =
afl->core_operator_finds_puppet[i];
} }
@ -4198,11 +4237,16 @@ pacemaker_fuzzing:
} /* if afl->swarm_now == swarm_num */ } /* if afl->swarm_now == swarm_num */
/* adjust pointers dependent on 'afl->swarm_now' */ /* adjust pointers dependent on 'afl->swarm_now' */
afl->mopt_globals_pilot.finds = afl->stage_finds_puppet[afl->swarm_now]; afl->mopt_globals_pilot.finds =
afl->mopt_globals_pilot.finds_v2 = afl->stage_finds_puppet_v2[afl->swarm_now]; afl->stage_finds_puppet[afl->swarm_now];
afl->mopt_globals_pilot.cycles = afl->stage_cycles_puppet[afl->swarm_now]; afl->mopt_globals_pilot.finds_v2 =
afl->mopt_globals_pilot.cycles_v2 = afl->stage_cycles_puppet_v2[afl->swarm_now]; afl->stage_finds_puppet_v2[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v3 = afl->stage_cycles_puppet_v3[afl->swarm_now]; afl->mopt_globals_pilot.cycles =
afl->stage_cycles_puppet[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v2 =
afl->stage_cycles_puppet_v2[afl->swarm_now];
afl->mopt_globals_pilot.cycles_v3 =
afl->stage_cycles_puppet_v3[afl->swarm_now];
} else { } else {
@ -4225,18 +4269,24 @@ pacemaker_fuzzing:
#undef FLIP_BIT #undef FLIP_BIT
u8 core_fuzzing(afl_state_t* afl) { u8 core_fuzzing(afl_state_t* afl) {
return mopt_common_fuzzing(afl, afl->mopt_globals_core); return mopt_common_fuzzing(afl, afl->mopt_globals_core);
} }
u8 pilot_fuzzing(afl_state_t* afl) { u8 pilot_fuzzing(afl_state_t* afl) {
return mopt_common_fuzzing(afl, afl->mopt_globals_pilot); return mopt_common_fuzzing(afl, afl->mopt_globals_pilot);
} }
void pso_updating(afl_state_t* afl) { void pso_updating(afl_state_t* afl) {
afl->g_now += 1; afl->g_now += 1;
if (afl->g_now > afl->g_max) afl->g_now = 0; if (afl->g_now > afl->g_max) afl->g_now = 0;
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) + afl->w_end; afl->w_now =
(afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) +
afl->w_end;
int tmp_swarm, i, j; int tmp_swarm, i, j;
u64 temp_operator_finds_puppet = 0; u64 temp_operator_finds_puppet = 0;
for (i = 0; i < operator_num; ++i) { for (i = 0; i < operator_num; ++i) {
@ -4353,3 +4403,4 @@ u8 fuzz_one(afl_state_t *afl) {
return key_val_lv; return key_val_lv;
} }

View File

@ -144,6 +144,7 @@ void finalize_py_module(afl_state_t *afl) {
} }
void init_py(afl_state_t *afl, unsigned int seed) { void init_py(afl_state_t *afl, unsigned int seed) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
/* Provide the init function a seed for the Python RNG */ /* Provide the init function a seed for the Python RNG */
@ -379,7 +380,8 @@ void trim_py(afl_state_t *afl, u8** out_buf, size_t* out_buf_size) {
} }
size_t havoc_mutation_py(afl_state_t *afl, u8** buf, size_t buf_size, size_t max_size) { size_t havoc_mutation_py(afl_state_t *afl, u8 **buf, size_t buf_size,
size_t max_size) {
size_t mutated_size; size_t mutated_size;
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
@ -411,7 +413,8 @@ size_t havoc_mutation_py(afl_state_t *afl, u8** buf, size_t buf_size, size_t max
PyTuple_SetItem(py_args, 1, py_value); PyTuple_SetItem(py_args, 1, py_value);
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION], py_args); py_value =
PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
@ -439,8 +442,8 @@ u8 havoc_mutation_probability_py(afl_state_t *afl) {
PyObject *py_args, *py_value; PyObject *py_args, *py_value;
py_args = PyTuple_New(0); py_args = PyTuple_New(0);
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_value = PyObject_CallObject(
py_args); afl->py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
if (py_value != NULL) { if (py_value != NULL) {
@ -549,8 +552,8 @@ void queue_new_entry_py(afl_state_t *afl, const u8* filename_new_queue,
PyTuple_SetItem(py_args, 1, py_value); PyTuple_SetItem(py_args, 1, py_value);
// Call // Call
py_value = PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_value =
py_args); PyObject_CallObject(afl->py_functions[PY_FUNC_QUEUE_NEW_ENTRY], py_args);
Py_DECREF(py_args); Py_DECREF(py_args);
if (py_value == NULL) { if (py_value == NULL) {

View File

@ -33,7 +33,8 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry* q) {
u8* fn = strrchr(q->fname, '/'); u8* fn = strrchr(q->fname, '/');
s32 fd; s32 fd;
fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir, fn + 1); fn = alloc_printf("%s/queue/.state/deterministic_done/%s", afl->out_dir,
fn + 1);
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0) PFATAL("Unable to create '%s'", fn); if (fd < 0) PFATAL("Unable to create '%s'", fn);
@ -176,9 +177,10 @@ void destroy_queue(afl_state_t *afl) {
seen in the bitmap so far, and focus on fuzzing them at the expense of seen in the bitmap so far, and focus on fuzzing them at the expense of
the rest. the rest.
The first step of the process is to maintain a list of afl->top_rated[] entries The first step of the process is to maintain a list of afl->top_rated[]
for every byte in the bitmap. We win that slot if there is no previous entries for every byte in the bitmap. We win that slot if there is no
contender, or if the contender has a more favorable speed x size factor. */ previous contender, or if the contender has a more favorable speed x size
factor. */
void update_bitmap_score(afl_state_t* afl, struct queue_entry* q) { void update_bitmap_score(afl_state_t* afl, struct queue_entry* q) {
@ -186,8 +188,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
u64 fav_factor = q->exec_us * q->len; u64 fav_factor = q->exec_us * q->len;
u64 fuzz_p2 = next_p2(q->n_fuzz); u64 fuzz_p2 = next_p2(q->n_fuzz);
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous winner, /* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
and how it compares to us. */ winner, and how it compares to us. */
for (i = 0; i < MAP_SIZE; ++i) for (i = 0; i < MAP_SIZE; ++i)
@ -197,7 +199,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
/* Faster-executing or smaller test cases are favored. */ /* Faster-executing or smaller test cases are favored. */
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz); u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
u64 top_rated_fav_factor = afl->top_rated[i]->exec_us * afl->top_rated[i]->len; u64 top_rated_fav_factor =
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
if (fuzz_p2 > top_rated_fuzz_p2) { if (fuzz_p2 > top_rated_fuzz_p2) {
@ -209,7 +212,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry* q) {
} }
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len) continue; if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
continue;
/* Looks like we're going to win. Decrease ref count for the /* Looks like we're going to win. Decrease ref count for the
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */ previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
@ -459,7 +463,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry* q) {
/* Make sure that we don't go over limit. */ /* Make sure that we don't go over limit. */
if (perf_score > afl->havoc_max_mult * 100) perf_score = afl->havoc_max_mult * 100; if (perf_score > afl->havoc_max_mult * 100)
perf_score = afl->havoc_max_mult * 100;
return perf_score; return perf_score;

View File

@ -117,7 +117,8 @@ static u8 colorization(afl_state_t *afl, u8* buf, u32 len, u32 exec_cksum) {
struct range* rng; struct range* rng;
afl->stage_cur = 0; afl->stage_cur = 0;
while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { while ((rng = pop_biggest_range(&ranges)) != NULL &&
afl->stage_cur < afl->stage_max) {
u32 s = rng->end - rng->start; u32 s = rng->end - rng->start;
if (s == 0) goto empty_range; if (s == 0) goto empty_range;
@ -223,9 +224,9 @@ static u8 its_fuzz(afl_state_t *afl, u8* buf, u32 len, u8* status) {
} }
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 pattern, u64 repl, u32 idx, static u8 cmp_extend_encoding(afl_state_t* afl, struct cmp_header* h,
u8* orig_buf, u8* buf, u32 len, u8 do_reverse, u64 pattern, u64 repl, u32 idx, u8* orig_buf,
u8* status) { u8* buf, u32 len, u8 do_reverse, u8* status) {
u64* buf_64 = (u64*)&buf[idx]; u64* buf_64 = (u64*)&buf[idx];
u32* buf_32 = (u32*)&buf[idx]; u32* buf_32 = (u32*)&buf[idx];
@ -251,8 +252,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -270,8 +271,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -289,8 +290,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header* h, u64 patter
// reverse encoding // reverse encoding
if (do_reverse) if (do_reverse)
if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl), idx, if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl),
orig_buf, buf, len, 0, status))) idx, orig_buf, buf, len, 0, status)))
return 1; return 1;
} }
@ -372,21 +373,22 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
// opt not in the paper // opt not in the paper
for (j = 0; j < i; ++j) for (j = 0; j < i; ++j)
if (afl->shm.cmp_map->log[key][j].v0 == o->v0 && afl->shm.cmp_map->log[key][i].v1 == o->v1) if (afl->shm.cmp_map->log[key][j].v0 == o->v0 &&
afl->shm.cmp_map->log[key][i].v1 == o->v1)
goto cmp_fuzz_next_iter; goto cmp_fuzz_next_iter;
for (idx = 0; idx < len && fails < 8; ++idx) { for (idx = 0; idx < len && fails < 8; ++idx) {
if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf,
1, &status))) len, 1, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
else if (status == 1) else if (status == 1)
break; break;
if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf,
1, &status))) len, 1, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
@ -412,8 +414,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
} }
static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header* h, u8* pattern, u8* repl, u32 idx, static u8 rtn_extend_encoding(afl_state_t* afl, struct cmp_header* h,
u8* orig_buf, u8* buf, u32 len, u8* status) { u8* pattern, u8* repl, u32 idx, u8* orig_buf,
u8* buf, u32 len, u8* status) {
u32 i; u32 i;
u32 its_len = MIN(32, len - idx); u32 its_len = MIN(32, len - idx);
@ -451,7 +454,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
for (i = 0; i < loggeds; ++i) { for (i = 0; i < loggeds; ++i) {
struct cmpfn_operands* o = &((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[i]; struct cmpfn_operands* o =
&((struct cmpfn_operands*)afl->shm.cmp_map->log[key])[i];
// opt not in the paper // opt not in the paper
for (j = 0; j < i; ++j) for (j = 0; j < i; ++j)
@ -461,16 +465,16 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8* orig_buf, u8* buf, u32 len) {
for (idx = 0; idx < len && fails < 8; ++idx) { for (idx = 0; idx < len && fails < 8; ++idx) {
if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf, len, if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, idx, orig_buf, buf,
&status))) len, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;
else if (status == 1) else if (status == 1)
break; break;
if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf, len, if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, idx, orig_buf, buf,
&status))) len, &status)))
return 1; return 1;
if (status == 2) if (status == 2)
++fails; ++fails;

View File

@ -81,8 +81,9 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */ setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
/* Isolate the process and configure standard descriptors. If afl->fsrv.out_file is /* Isolate the process and configure standard descriptors. If
specified, stdin is /dev/null; otherwise, afl->fsrv.out_fd is cloned instead. */ afl->fsrv.out_file is specified, stdin is /dev/null; otherwise,
afl->fsrv.out_fd is cloned instead. */
setsid(); setsid();
@ -165,11 +166,13 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_REAL, &it, NULL);
/* The SIGALRM handler simply kills the afl->fsrv.child_pid and sets afl->fsrv.child_timed_out. */ /* The SIGALRM handler simply kills the afl->fsrv.child_pid and sets
* afl->fsrv.child_timed_out. */
if (afl->dumb_mode == 1 || afl->no_forkserver) { if (afl->dumb_mode == 1 || afl->no_forkserver) {
if (waitpid(afl->fsrv.child_pid, &status, 0) <= 0) PFATAL("waitpid() failed"); if (waitpid(afl->fsrv.child_pid, &status, 0) <= 0)
PFATAL("waitpid() failed");
} else { } else {
@ -218,8 +221,8 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
++afl->total_execs; ++afl->total_execs;
/* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the /* Any subsequent operations on afl->fsrv.trace_bits must not be moved by the
compiler below this point. Past this location, afl->fsrv.trace_bits[] behave compiler below this point. Past this location, afl->fsrv.trace_bits[]
very normally and do not have to be treated as volatile. */ behave very normally and do not have to be treated as volatile. */
MEM_BARRIER(); MEM_BARRIER();
@ -239,7 +242,8 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
afl->kill_signal = WTERMSIG(status); afl->kill_signal = WTERMSIG(status);
if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL) return FAULT_TMOUT; if (afl->fsrv.child_timed_out && afl->kill_signal == SIGKILL)
return FAULT_TMOUT;
return FAULT_CRASH; return FAULT_CRASH;
@ -262,9 +266,9 @@ u8 run_target(afl_state_t *afl, u32 timeout) {
} }
/* Write modified data to file for testing. If afl->fsrv.out_file is set, the old file /* Write modified data to file for testing. If afl->fsrv.out_file is set, the
is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is rewound and old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is
truncated. */ rewound and truncated. */
void write_to_testcase(afl_state_t* afl, void* mem, u32 len) { void write_to_testcase(afl_state_t* afl, void* mem, u32 len) {
@ -272,8 +276,8 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
#ifdef _AFL_DOCUMENT_MUTATIONS #ifdef _AFL_DOCUMENT_MUTATIONS
s32 doc_fd; s32 doc_fd;
char* fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir, afl->document_counter++, char* fn = alloc_printf("%s/mutations/%09u:%s", afl->out_dir,
describe_op(0)); afl->document_counter++, describe_op(0));
if (fn != NULL) { if (fn != NULL) {
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) { if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
@ -312,7 +316,8 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
if (afl->mutator && afl->mutator->afl_custom_pre_save) { if (afl->mutator && afl->mutator->afl_custom_pre_save) {
u8* new_data; u8* new_data;
size_t new_size = afl->mutator->afl_custom_pre_save(afl, mem, len, &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_write(fd, new_data, new_size, afl->fsrv.out_file);
ck_free(new_data); ck_free(new_data);
@ -335,7 +340,8 @@ void write_to_testcase(afl_state_t *afl, void* mem, u32 len) {
/* The same, but with an adjustable gap. Used for trimming. */ /* The same, but with an adjustable gap. Used for trimming. */
static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u32 skip_len) { static void write_with_gap(afl_state_t* afl, void* mem, u32 len, u32 skip_at,
u32 skip_len) {
s32 fd = afl->fsrv.out_fd; s32 fd = afl->fsrv.out_fd;
u32 tail_len = len - skip_at - skip_len; u32 tail_len = len - skip_at - skip_len;
@ -362,7 +368,8 @@ static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u3
if (skip_at) ck_write(fd, mem, skip_at, afl->fsrv.out_file); if (skip_at) ck_write(fd, mem, skip_at, afl->fsrv.out_file);
u8* memu8 = mem; u8* memu8 = mem;
if (tail_len) ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file); if (tail_len)
ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file);
if (!afl->fsrv.out_file) { if (!afl->fsrv.out_file) {
@ -379,8 +386,8 @@ static void write_with_gap(afl_state_t *afl, void* mem, u32 len, u32 skip_at, u3
to warn about flaky or otherwise problematic test cases early on; and when to warn about flaky or otherwise problematic test cases early on; and when
new paths are discovered to detect variable behavior and so on. */ new paths are discovered to detect variable behavior and so on. */
u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 handicap, u8 calibrate_case(afl_state_t* afl, struct queue_entry* q, u8* use_mem,
u8 from_queue) { u32 handicap, u8 from_queue) {
static u8 first_trace[MAP_SIZE]; static u8 first_trace[MAP_SIZE];
@ -398,8 +405,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
to intermittent latency. */ to intermittent latency. */
if (!from_queue || afl->resuming_fuzz) if (!from_queue || afl->resuming_fuzz)
use_tmout = use_tmout = MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD,
MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD, afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100); afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100);
++q->cal_failed; ++q->cal_failed;
@ -409,8 +416,10 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
/* Make sure the forkserver is up before we do anything, and let's not /* Make sure the forkserver is up before we do anything, and let's not
count its spin-up time toward binary calibration. */ count its spin-up time toward binary calibration. */
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->fsrv.fsrv_pid) afl_fsrv_start(&afl->fsrv, afl->argv); if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->fsrv.fsrv_pid)
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid && afl->shm.cmplog_mode) afl_fsrv_start(&afl->fsrv, afl->argv);
if (afl->dumb_mode != 1 && !afl->no_forkserver && !afl->cmplog_fsrv_pid &&
afl->shm.cmplog_mode)
init_cmplog_forkserver(afl); init_cmplog_forkserver(afl);
if (q->exec_cksum) memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE); if (q->exec_cksum) memcpy(first_trace, afl->fsrv.trace_bits, MAP_SIZE);
@ -421,7 +430,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
u32 cksum; u32 cksum;
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) show_stats(afl); if (!first_run && !(afl->stage_cur % afl->stats_update_freq))
show_stats(afl);
write_to_testcase(afl, use_mem, q->len); write_to_testcase(afl, use_mem, q->len);
@ -432,7 +442,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry* q, u8* use_mem, u32 hand
if (afl->stop_soon || fault != afl->crash_mode) goto abort_calibration; if (afl->stop_soon || fault != afl->crash_mode) goto abort_calibration;
if (!afl->dumb_mode && !afl->stage_cur && !count_bytes(afl->fsrv.trace_bits)) { if (!afl->dumb_mode && !afl->stage_cur &&
!count_bytes(afl->fsrv.trace_bits)) {
fault = FAULT_NOINST; fault = FAULT_NOINST;
goto abort_calibration; goto abort_calibration;
@ -562,7 +573,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* Skip dot files and our own output directory. */ /* Skip dot files and our own output directory. */
if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name)) continue; if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name))
continue;
/* Skip anything that doesn't have a queue/ subdirectory. */ /* Skip anything that doesn't have a queue/ subdirectory. */
@ -577,7 +589,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* Retrieve the ID of the last seen test case. */ /* Retrieve the ID of the last seen test case. */
qd_synced_path = alloc_printf("%s/.synced/%s", afl->out_dir, sd_ent->d_name); qd_synced_path =
alloc_printf("%s/.synced/%s", afl->out_dir, sd_ent->d_name);
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600); id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
@ -610,7 +623,8 @@ void sync_fuzzers(afl_state_t *afl) {
/* OK, sounds like a new one. Let's give it a try. */ /* OK, sounds like a new one. Let's give it a try. */
if (afl->syncing_case >= next_min_accept) next_min_accept = afl->syncing_case + 1; if (afl->syncing_case >= next_min_accept)
next_min_accept = afl->syncing_case + 1;
path = alloc_printf("%s/%s", qd_path, qd_ent->d_name); path = alloc_printf("%s/%s", qd_path, qd_ent->d_name);
@ -646,7 +660,8 @@ void sync_fuzzers(afl_state_t *afl) {
if (afl->stop_soon) goto close_sync; if (afl->stop_soon) goto close_sync;
afl->syncing_party = sd_ent->d_name; afl->syncing_party = sd_ent->d_name;
afl->queued_imported += save_if_interesting(afl, mem, st.st_size, fault); afl->queued_imported +=
save_if_interesting(afl, mem, st.st_size, fault);
afl->syncing_party = 0; afl->syncing_party = 0;
munmap(mem, st.st_size); munmap(mem, st.st_size);
@ -859,7 +874,8 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8* out_buf, u32 len) {
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault); afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault);
if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 == afl->stage_max) if (!(afl->stage_cur % afl->stats_update_freq) ||
afl->stage_cur + 1 == afl->stage_max)
show_stats(afl); show_stats(afl);
return 0; return 0;

View File

@ -27,7 +27,8 @@
/* Update stats file for unattended monitoring. */ /* Update stats file for unattended monitoring. */
void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, double eps) { void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
double eps) {
static double last_bcvg, last_stab, last_eps; static double last_bcvg, last_stab, last_eps;
static struct rusage rus; static struct rusage rus;
@ -101,23 +102,28 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, dou
"command_line : %s\n", "command_line : %s\n",
afl->start_time / 1000, get_cur_time() / 1000, getpid(), afl->start_time / 1000, get_cur_time() / 1000, getpid(),
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs, afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
/*eps,*/ afl->total_execs / ((double)(get_cur_time() - afl->start_time) / 1000), /*eps,*/ afl->total_execs /
afl->queued_paths, afl->queued_favored, afl->queued_discovered, afl->queued_imported, ((double)(get_cur_time() - afl->start_time) / 1000),
afl->max_depth, afl->current_entry, afl->pending_favored, afl->pending_not_fuzzed, afl->queued_paths, afl->queued_favored, afl->queued_discovered,
afl->queued_variable, stability, bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->queued_imported, afl->max_depth, afl->current_entry,
afl->last_path_time / 1000, afl->last_crash_time / 1000, afl->last_hang_time / 1000, afl->pending_favored, afl->pending_not_fuzzed, afl->queued_variable,
afl->total_execs - afl->last_crash_execs, afl->fsrv.exec_tmout, afl->slowest_exec_ms, stability, bitmap_cvg, afl->unique_crashes, afl->unique_hangs,
afl->last_path_time / 1000, afl->last_crash_time / 1000,
afl->last_hang_time / 1000, afl->total_execs - afl->last_crash_execs,
afl->fsrv.exec_tmout, afl->slowest_exec_ms,
#ifdef __APPLE__ #ifdef __APPLE__
(unsigned long int)(rus.ru_maxrss >> 20), (unsigned long int)(rus.ru_maxrss >> 20),
#else #else
(unsigned long int)(rus.ru_maxrss >> 10), (unsigned long int)(rus.ru_maxrss >> 10),
#endif #endif
afl->use_banner, afl->unicorn_mode ? "unicorn" : "", afl->qemu_mode ? "qemu " : "", afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->dumb_mode ? " dumb " : "", afl->no_forkserver ? "no_fsrv " : "", afl->qemu_mode ? "qemu " : "", afl->dumb_mode ? " dumb " : "",
afl->crash_mode ? "crash " : "", afl->persistent_mode ? "persistent " : "", afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
afl->persistent_mode ? "persistent " : "",
afl->deferred_mode ? "deferred " : "", afl->deferred_mode ? "deferred " : "",
(afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode || afl->no_forkserver || afl->crash_mode || (afl->unicorn_mode || afl->qemu_mode || afl->dumb_mode ||
afl->persistent_mode || afl->deferred_mode) afl->no_forkserver || afl->crash_mode || afl->persistent_mode ||
afl->deferred_mode)
? "" ? ""
: "default", : "default",
afl->orig_cmdline); afl->orig_cmdline);
@ -157,9 +163,10 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
fprintf(afl->fsrv.plot_file, fprintf(afl->fsrv.plot_file,
"%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\n", "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\n",
get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, afl->queued_paths, get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg, afl->unique_crashes, afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
afl->unique_hangs, afl->max_depth, eps); /* ignore errors */ bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth,
eps); /* ignore errors */
fflush(afl->fsrv.plot_file); fflush(afl->fsrv.plot_file);
@ -266,11 +273,12 @@ void show_stats(afl_state_t *afl) {
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */ /* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
if (!afl->dumb_mode && afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed && if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
get_afl_env("AFL_EXIT_WHEN_DONE")) !afl->pending_not_fuzzed && get_afl_env("AFL_EXIT_WHEN_DONE"))
afl->stop_soon = 2; afl->stop_soon = 2;
if (afl->total_crashes && get_afl_env("AFL_BENCH_UNTIL_CRASH")) afl->stop_soon = 2; if (afl->total_crashes && get_afl_env("AFL_BENCH_UNTIL_CRASH"))
afl->stop_soon = 2;
/* If we're not on TTY, bail out. */ /* If we're not on TTY, bail out. */
@ -305,18 +313,20 @@ void show_stats(afl_state_t *afl) {
/* Let's start by drawing a centered banner. */ /* Let's start by drawing a centered banner. */
banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) + strlen(afl->use_banner) + banner_len = (afl->crash_mode ? 24 : 22) + strlen(VERSION) +
strlen(afl->power_name) + 3 + 5; strlen(afl->use_banner) + strlen(afl->power_name) + 3 + 5;
banner_pad = (79 - banner_len) / 2; banner_pad = (79 - banner_len) / 2;
memset(tmp, ' ', banner_pad); memset(tmp, ' ', banner_pad);
#ifdef HAVE_AFFINITY #ifdef HAVE_AFFINITY
sprintf(tmp + banner_pad, sprintf(
tmp + banner_pad,
"%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}", "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]" cBLU " {%d}",
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop", afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name, afl->cpu_aff); afl->use_banner, afl->power_name, afl->cpu_aff);
#else #else
sprintf(tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]", sprintf(
tmp + banner_pad, "%s " cLCY VERSION cLGN " (%s) " cPIN "[%s]",
afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop", afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop",
afl->use_banner, afl->power_name); afl->use_banner, afl->power_name);
#endif /* HAVE_AFFINITY */ #endif /* HAVE_AFFINITY */
@ -360,7 +370,8 @@ void show_stats(afl_state_t *afl) {
else else
/* No finds for a long time and no test cases to try. */ /* No finds for a long time and no test cases to try. */
if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed && min_wo_finds > 120) if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
min_wo_finds > 120)
strcpy(tmp, cLGN); strcpy(tmp, cLGN);
/* Default: cautiously OK to stop? */ /* Default: cautiously OK to stop? */
@ -376,7 +387,8 @@ void show_stats(afl_state_t *afl) {
/* We want to warn people about not seeing new paths after a full cycle, /* We want to warn people about not seeing new paths after a full cycle,
except when resuming fuzzing or running in non-instrumented mode. */ except when resuming fuzzing or running in non-instrumented mode. */
if (!afl->dumb_mode && (afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 || if (!afl->dumb_mode &&
(afl->last_path_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
afl->in_bitmap || afl->crash_mode)) { afl->in_bitmap || afl->crash_mode)) {
SAYF(bV bSTOP " last new path : " cRST "%-33s ", SAYF(bV bSTOP " last new path : " cRST "%-33s ",
@ -407,7 +419,8 @@ void show_stats(afl_state_t *afl) {
SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP SAYF(bV bSTOP " last uniq crash : " cRST "%-33s " bSTG bV bSTOP
" uniq crashes : %s%-6s" bSTG bV "\n", " uniq crashes : %s%-6s" bSTG bV "\n",
DTD(cur_ms, afl->last_crash_time), afl->unique_crashes ? cLRD : cRST, tmp); DTD(cur_ms, afl->last_crash_time), afl->unique_crashes ? cLRD : cRST,
tmp);
sprintf(tmp, "%s%s", DI(afl->unique_hangs), sprintf(tmp, "%s%s", DI(afl->unique_hangs),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
@ -434,7 +447,8 @@ void show_stats(afl_state_t *afl) {
((double)afl->queue_cur->bitmap_size) * 100 / MAP_SIZE, t_byte_ratio); ((double)afl->queue_cur->bitmap_size) * 100 / MAP_SIZE, t_byte_ratio);
SAYF(" map density : %s%-21s" bSTG bV "\n", SAYF(" map density : %s%-21s" bSTG bV "\n",
t_byte_ratio > 70 ? cLRD : ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST), t_byte_ratio > 70 ? cLRD
: ((t_bytes < 200 && !afl->dumb_mode) ? cPIN : cRST),
tmp); tmp);
sprintf(tmp, "%s (%0.02f%%)", DI(afl->cur_skipped_paths), sprintf(tmp, "%s (%0.02f%%)", DI(afl->cur_skipped_paths),
@ -477,7 +491,8 @@ void show_stats(afl_state_t *afl) {
SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp); SAYF(" new edges on : " cRST "%-22s" bSTG bV "\n", tmp);
sprintf(tmp, "%s (%s%s unique)", DI(afl->total_crashes), DI(afl->unique_crashes), sprintf(tmp, "%s (%s%s unique)", DI(afl->total_crashes),
DI(afl->unique_crashes),
(afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : ""); (afl->unique_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
if (afl->crash_mode) { if (afl->crash_mode) {
@ -510,7 +525,8 @@ void show_stats(afl_state_t *afl) {
} }
sprintf(tmp, "%s (%s%s unique)", DI(afl->total_tmouts), DI(afl->unique_tmouts), sprintf(tmp, "%s (%s%s unique)", DI(afl->total_tmouts),
DI(afl->unique_tmouts),
(afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : ""); (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp); SAYF(bSTG bV bSTOP " total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
@ -527,7 +543,8 @@ void show_stats(afl_state_t *afl) {
} else { } else {
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP1]), sprintf(
tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP1]),
DI(afl->stage_cycles[STAGE_FLIP1]), DI(afl->stage_finds[STAGE_FLIP2]), DI(afl->stage_cycles[STAGE_FLIP1]), DI(afl->stage_finds[STAGE_FLIP2]),
DI(afl->stage_cycles[STAGE_FLIP2]), DI(afl->stage_finds[STAGE_FLIP4]), DI(afl->stage_cycles[STAGE_FLIP2]), DI(afl->stage_finds[STAGE_FLIP4]),
DI(afl->stage_cycles[STAGE_FLIP4])); DI(afl->stage_cycles[STAGE_FLIP4]));
@ -539,7 +556,8 @@ void show_stats(afl_state_t *afl) {
tmp, DI(afl->max_depth)); tmp, DI(afl->max_depth));
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP8]), sprintf(
tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_FLIP8]),
DI(afl->stage_cycles[STAGE_FLIP8]), DI(afl->stage_finds[STAGE_FLIP16]), DI(afl->stage_cycles[STAGE_FLIP8]), DI(afl->stage_finds[STAGE_FLIP16]),
DI(afl->stage_cycles[STAGE_FLIP16]), DI(afl->stage_finds[STAGE_FLIP32]), DI(afl->stage_cycles[STAGE_FLIP16]), DI(afl->stage_finds[STAGE_FLIP32]),
DI(afl->stage_cycles[STAGE_FLIP32])); DI(afl->stage_cycles[STAGE_FLIP32]));
@ -550,8 +568,10 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_ARITH8]), sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_ARITH8]),
DI(afl->stage_cycles[STAGE_ARITH8]), DI(afl->stage_finds[STAGE_ARITH16]), DI(afl->stage_cycles[STAGE_ARITH8]),
DI(afl->stage_cycles[STAGE_ARITH16]), DI(afl->stage_finds[STAGE_ARITH32]), DI(afl->stage_finds[STAGE_ARITH16]),
DI(afl->stage_cycles[STAGE_ARITH16]),
DI(afl->stage_finds[STAGE_ARITH32]),
DI(afl->stage_cycles[STAGE_ARITH32])); DI(afl->stage_cycles[STAGE_ARITH32]));
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
@ -559,10 +579,11 @@ void show_stats(afl_state_t *afl) {
tmp, DI(afl->pending_favored)); tmp, DI(afl->pending_favored));
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf( sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_INTEREST8]),
tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_INTEREST8]), DI(afl->stage_cycles[STAGE_INTEREST8]),
DI(afl->stage_cycles[STAGE_INTEREST8]), DI(afl->stage_finds[STAGE_INTEREST16]), DI(afl->stage_finds[STAGE_INTEREST16]),
DI(afl->stage_cycles[STAGE_INTEREST16]), DI(afl->stage_finds[STAGE_INTEREST32]), DI(afl->stage_cycles[STAGE_INTEREST16]),
DI(afl->stage_finds[STAGE_INTEREST32]),
DI(afl->stage_cycles[STAGE_INTEREST32])); DI(afl->stage_cycles[STAGE_INTEREST32]));
SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP
@ -571,15 +592,18 @@ void show_stats(afl_state_t *afl) {
if (!afl->skip_deterministic) if (!afl->skip_deterministic)
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_EXTRAS_UO]), sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_EXTRAS_UO]),
DI(afl->stage_cycles[STAGE_EXTRAS_UO]), DI(afl->stage_finds[STAGE_EXTRAS_UI]), DI(afl->stage_cycles[STAGE_EXTRAS_UO]),
DI(afl->stage_cycles[STAGE_EXTRAS_UI]), DI(afl->stage_finds[STAGE_EXTRAS_AO]), DI(afl->stage_finds[STAGE_EXTRAS_UI]),
DI(afl->stage_cycles[STAGE_EXTRAS_UI]),
DI(afl->stage_finds[STAGE_EXTRAS_AO]),
DI(afl->stage_cycles[STAGE_EXTRAS_AO])); DI(afl->stage_cycles[STAGE_EXTRAS_AO]));
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
" imported : " cRST "%-10s" bSTG bV "\n", " imported : " cRST "%-10s" bSTG bV "\n",
tmp, afl->sync_id ? DI(afl->queued_imported) : (u8 *)"n/a"); tmp, afl->sync_id ? DI(afl->queued_imported) : (u8 *)"n/a");
sprintf(tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_HAVOC]), sprintf(
tmp, "%s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_HAVOC]),
DI(afl->stage_cycles[STAGE_HAVOC]), DI(afl->stage_finds[STAGE_SPLICE]), DI(afl->stage_cycles[STAGE_HAVOC]), DI(afl->stage_finds[STAGE_SPLICE]),
DI(afl->stage_cycles[STAGE_SPLICE]), DI(afl->stage_finds[STAGE_RADAMSA]), DI(afl->stage_cycles[STAGE_SPLICE]), DI(afl->stage_finds[STAGE_RADAMSA]),
DI(afl->stage_cycles[STAGE_RADAMSA])); DI(afl->stage_cycles[STAGE_RADAMSA]));
@ -594,20 +618,22 @@ void show_stats(afl_state_t *afl) {
SAYF(" stability : %s%-10s" bSTG bV "\n", SAYF(" stability : %s%-10s" bSTG bV "\n",
(stab_ratio < 85 && afl->var_byte_count > 40) (stab_ratio < 85 && afl->var_byte_count > 40)
? cLRD ? cLRD
: ((afl->queued_variable && (!afl->persistent_mode || afl->var_byte_count > 20)) : ((afl->queued_variable &&
(!afl->persistent_mode || afl->var_byte_count > 20))
? cMGN ? cMGN
: cRST), : cRST),
tmp); tmp);
if (afl->shm.cmplog_mode) { if (afl->shm.cmplog_mode) {
sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s", DI(afl->stage_finds[STAGE_PYTHON]), sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
DI(afl->stage_finds[STAGE_PYTHON]),
DI(afl->stage_cycles[STAGE_PYTHON]), DI(afl->stage_cycles[STAGE_PYTHON]),
DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]), DI(afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]), DI(afl->stage_cycles[STAGE_CUSTOM_MUTATOR]),
DI(afl->stage_finds[STAGE_COLORIZATION]), DI(afl->stage_finds[STAGE_COLORIZATION]),
DI(afl->stage_cycles[STAGE_COLORIZATION]), DI(afl->stage_finds[STAGE_ITS]), DI(afl->stage_cycles[STAGE_COLORIZATION]),
DI(afl->stage_cycles[STAGE_ITS])); DI(afl->stage_finds[STAGE_ITS]), DI(afl->stage_cycles[STAGE_ITS]));
SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n", SAYF(bV bSTOP " custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
tmp); tmp);
@ -631,7 +657,8 @@ void show_stats(afl_state_t *afl) {
} else { } else {
sprintf(tmp, "%0.02f%%/%s, ", sprintf(tmp, "%0.02f%%/%s, ",
((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 / afl->bytes_trim_in, ((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 /
afl->bytes_trim_in,
DI(afl->trim_execs)); DI(afl->trim_execs));
} }
@ -789,7 +816,8 @@ void show_init_stats(afl_state_t *afl) {
"%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST "%u favored, %u variable, %u total\n" cGRA " Bitmap range : " cRST
"%u to %u bits (average: %0.02f bits)\n" cGRA "%u to %u bits (average: %0.02f bits)\n" cGRA
" Exec timing : " cRST "%s to %s us (average: %s us)\n", " Exec timing : " cRST "%s to %s us (average: %s us)\n",
afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits, max_bits, afl->queued_favored, afl->queued_variable, afl->queued_paths, min_bits,
max_bits,
((double)afl->total_bitmap_size) / ((double)afl->total_bitmap_size) /
(afl->total_bitmap_entries ? afl->total_bitmap_entries : 1), (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1),
DI(min_us), DI(max_us), DI(avg_us)); DI(min_us), DI(max_us), DI(avg_us));
@ -811,9 +839,11 @@ void show_init_stats(afl_state_t *afl) {
afl->fsrv.exec_tmout = avg_us * 5 / 1000; afl->fsrv.exec_tmout = avg_us * 5 / 1000;
afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000); afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000);
afl->fsrv.exec_tmout = (afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND; afl->fsrv.exec_tmout =
(afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;
if (afl->fsrv.exec_tmout > EXEC_TIMEOUT) afl->fsrv.exec_tmout = EXEC_TIMEOUT; if (afl->fsrv.exec_tmout > EXEC_TIMEOUT)
afl->fsrv.exec_tmout = EXEC_TIMEOUT;
ACTF("No -t option specified, so I'll use exec timeout of %u ms.", ACTF("No -t option specified, so I'll use exec timeout of %u ms.",
afl->fsrv.exec_tmout); afl->fsrv.exec_tmout);
@ -822,7 +852,8 @@ void show_init_stats(afl_state_t *afl) {
} else if (afl->timeout_given == 3) { } else if (afl->timeout_given == 3) {
ACTF("Applying timeout settings from resumed session (%u ms).", afl->fsrv.exec_tmout); ACTF("Applying timeout settings from resumed session (%u ms).",
afl->fsrv.exec_tmout);
} }

View File

@ -222,7 +222,6 @@ static int stricmp(char const* a, char const* b) {
} }
/* Main entry point */ /* Main entry point */
int main(int argc, char** argv, char** envp) { int main(int argc, char** argv, char** envp) {
@ -239,9 +238,7 @@ int main(int argc, char** argv, char** envp) {
struct timezone tz; struct timezone tz;
afl_state_t* afl = calloc(1, sizeof(afl_state_t)); afl_state_t* afl = calloc(1, sizeof(afl_state_t));
if (!afl) { if (!afl) { FATAL("Could not create afl state"); }
FATAL("Could not create afl state");
}
afl_state_init(afl); afl_state_init(afl);
afl_fsrv_init(&afl->fsrv); afl_fsrv_init(&afl->fsrv);
@ -348,8 +345,8 @@ int main(int argc, char** argv, char** envp) {
*c = 0; *c = 0;
if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 || if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
!afl->master_id || !afl->master_max || afl->master_id > afl->master_max || !afl->master_id || !afl->master_max ||
afl->master_max > 1000000) afl->master_id > afl->master_max || afl->master_max > 1000000)
FATAL("Bogus master ID passed to -M"); FATAL("Bogus master ID passed to -M");
} }
@ -543,7 +540,8 @@ int main(int argc, char** argv, char** envp) {
afl->limit_time_sig = 1; afl->limit_time_sig = 1;
afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT; afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
if (sscanf(optarg, "%llu", &afl->limit_time_puppet) < 1 || optarg[0] == '-') if (sscanf(optarg, "%llu", &afl->limit_time_puppet) < 1 ||
optarg[0] == '-')
FATAL("Bad syntax used for -L"); FATAL("Bad syntax used for -L");
u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000; u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000;
@ -561,7 +559,9 @@ int main(int argc, char** argv, char** envp) {
int tmp_swarm = 0; int tmp_swarm = 0;
if (afl->g_now > afl->g_max) afl->g_now = 0; if (afl->g_now > afl->g_max) afl->g_now = 0;
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) / (afl->g_max) + afl->w_end; afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) /
(afl->g_max) +
afl->w_end;
for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) { for (tmp_swarm = 0; tmp_swarm < swarm_num; ++tmp_swarm) {
@ -572,7 +572,8 @@ int main(int argc, char** argv, char** envp) {
afl->stage_finds_puppet[tmp_swarm][i] = 0; afl->stage_finds_puppet[tmp_swarm][i] = 0;
afl->probability_now[tmp_swarm][i] = 0.0; afl->probability_now[tmp_swarm][i] = 0.0;
afl->x_now[tmp_swarm][i] = ((double)(random() % 7000) * 0.0001 + 0.1); afl->x_now[tmp_swarm][i] =
((double)(random() % 7000) * 0.0001 + 0.1);
total_puppet_temp += afl->x_now[tmp_swarm][i]; total_puppet_temp += afl->x_now[tmp_swarm][i];
afl->v_now[tmp_swarm][i] = 0.1; afl->v_now[tmp_swarm][i] = 0.1;
afl->L_best[tmp_swarm][i] = 0.5; afl->L_best[tmp_swarm][i] = 0.5;
@ -587,7 +588,8 @@ int main(int argc, char** argv, char** envp) {
afl->stage_cycles_puppet[tmp_swarm][i]; afl->stage_cycles_puppet[tmp_swarm][i];
afl->stage_finds_puppet_v2[tmp_swarm][i] = afl->stage_finds_puppet_v2[tmp_swarm][i] =
afl->stage_finds_puppet[tmp_swarm][i]; afl->stage_finds_puppet[tmp_swarm][i];
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / total_puppet_temp; afl->x_now[tmp_swarm][i] =
afl->x_now[tmp_swarm][i] / total_puppet_temp;
} }
@ -598,7 +600,8 @@ int main(int argc, char** argv, char** envp) {
afl->probability_now[tmp_swarm][i] = 0.0; afl->probability_now[tmp_swarm][i] = 0.0;
afl->v_now[tmp_swarm][i] = afl->v_now[tmp_swarm][i] =
afl->w_now * afl->v_now[tmp_swarm][i] + afl->w_now * afl->v_now[tmp_swarm][i] +
RAND_C * (afl->L_best[tmp_swarm][i] - afl->x_now[tmp_swarm][i]) + RAND_C *
(afl->L_best[tmp_swarm][i] - afl->x_now[tmp_swarm][i]) +
RAND_C * (afl->G_best[i] - afl->x_now[tmp_swarm][i]); RAND_C * (afl->G_best[i] - afl->x_now[tmp_swarm][i]);
afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i]; afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i];
@ -617,7 +620,8 @@ int main(int argc, char** argv, char** envp) {
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp; afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp;
if (likely(i != 0)) if (likely(i != 0))
afl->probability_now[tmp_swarm][i] = afl->probability_now[tmp_swarm][i] =
afl->probability_now[tmp_swarm][i - 1] + afl->x_now[tmp_swarm][i]; afl->probability_now[tmp_swarm][i - 1] +
afl->x_now[tmp_swarm][i];
else else
afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i]; afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i];
@ -669,7 +673,8 @@ int main(int argc, char** argv, char** envp) {
OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL"); OKF("afl-tmin fork server patch from github.com/nccgroup/TriforceAFL");
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL"); OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
if (afl->sync_id && afl->force_deterministic && getenv("AFL_CUSTOM_MUTATOR_ONLY")) if (afl->sync_id && afl->force_deterministic &&
getenv("AFL_CUSTOM_MUTATOR_ONLY"))
WARNF( WARNF(
"Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will " "Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
"result in no deterministic mutations being done!"); "result in no deterministic mutations being done!");
@ -764,8 +769,7 @@ int main(int argc, char** argv, char** envp) {
if (get_afl_env("AFL_AUTORESUME")) { if (get_afl_env("AFL_AUTORESUME")) {
afl->autoresume = 1; afl->autoresume = 1;
if (afl->in_place_resume) if (afl->in_place_resume) SAYF("AFL_AUTORESUME has no effect for '-i -'");
SAYF("AFL_AUTORESUME has no effect for '-i -'");
} }
@ -886,10 +890,11 @@ int main(int argc, char** argv, char** envp) {
if (!afl->timeout_given) find_timeout(afl); if (!afl->timeout_given) find_timeout(afl);
if ((afl->tmp_dir = get_afl_env("AFL_TMPDIR")) != NULL && !afl->in_place_resume) { if ((afl->tmp_dir = get_afl_env("AFL_TMPDIR")) != NULL &&
!afl->in_place_resume) {
char tmpfile[afl->file_extension char tmpfile[afl->file_extension ? strlen(afl->tmp_dir) + 1 + 10 + 1 +
? strlen(afl->tmp_dir) + 1 + 10 + 1 + strlen(afl->file_extension) + 1 strlen(afl->file_extension) + 1
: strlen(afl->tmp_dir) + 1 + 10 + 1]; : strlen(afl->tmp_dir) + 1 + 10 + 1];
if (afl->file_extension) { if (afl->file_extension) {
@ -927,7 +932,8 @@ int main(int argc, char** argv, char** envp) {
if (afl->file_extension) { if (afl->file_extension) {
afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir, afl->file_extension); afl->fsrv.out_file = alloc_printf("%s/.cur_input.%s", afl->tmp_dir,
afl->file_extension);
} else { } else {
@ -935,7 +941,8 @@ int main(int argc, char** argv, char** envp) {
} }
detect_file_args(argv + optind + 1, afl->fsrv.out_file, afl->fsrv.use_stdin); detect_file_args(argv + optind + 1, afl->fsrv.out_file,
afl->fsrv.use_stdin);
break; break;
} }
@ -969,9 +976,11 @@ int main(int argc, char** argv, char** envp) {
if (afl->qemu_mode) { if (afl->qemu_mode) {
if (afl->use_wine) if (afl->use_wine)
use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind,
argv + optind);
} else { } else {
@ -1053,7 +1062,8 @@ int main(int argc, char** argv, char** envp) {
prev_queued = afl->queued_paths; prev_queued = afl->queued_paths;
if (afl->sync_id && afl->queue_cycle == 1 && get_afl_env("AFL_IMPORT_FIRST")) if (afl->sync_id && afl->queue_cycle == 1 &&
get_afl_env("AFL_IMPORT_FIRST"))
sync_fuzzers(afl); sync_fuzzers(afl);
} }
@ -1134,13 +1144,15 @@ stop_fuzzing:
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST, SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
afl->stop_soon == 2 ? "programmatically" : "by user"); afl->stop_soon == 2 ? "programmatically" : "by user");
if (afl->most_time_key == 2) SAYF(cYEL "[!] " cRST "Time limit was reached\n"); if (afl->most_time_key == 2)
SAYF(cYEL "[!] " cRST "Time limit was reached\n");
if (afl->most_execs_key == 2) if (afl->most_execs_key == 2)
SAYF(cYEL "[!] " cRST "Execution limit was reached\n"); SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
/* Running for more than 30 minutes but still doing first cycle? */ /* Running for more than 30 minutes but still doing first cycle? */
if (afl->queue_cycle == 1 && get_cur_time() - afl->start_time > 30 * 60 * 1000) { if (afl->queue_cycle == 1 &&
get_cur_time() - afl->start_time > 30 * 60 * 1000) {
SAYF("\n" cYEL "[!] " cRST SAYF("\n" cYEL "[!] " cRST
"Stopped during the first cycle, results may be incomplete.\n" "Stopped during the first cycle, results may be incomplete.\n"

View File

@ -124,7 +124,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random()); snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
/* create the shared memory segment as if it was a file */ /* create the shared memory segment as if it was a file */
shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600); shm->g_shm_fd =
shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); } if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */ /* configure the size of the shared memory segment */
@ -135,8 +136,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
} }
/* map the shared memory segment to the address space of the process */ /* map the shared memory segment to the address space of the process */
shm->map = shm->map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, map_size->g_shm_fd, 0); map_size->g_shm_fd, 0);
if (map_size->map == MAP_FAILED) { if (map_size->map == MAP_FAILED) {
close(map_size->g_shm_fd); close(map_size->g_shm_fd);
@ -203,7 +204,6 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
} }
#endif #endif
list_append(&shm_list, shm); list_append(&shm_list, shm);
@ -212,3 +212,4 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
return shm->map; return shm->map;
} }

View File

@ -259,7 +259,8 @@ static void write_to_testcase(afl_forkserver_t *fsrv, void* mem, u32 len) {
/* Execute target application. Returns 0 if the changes are a dud, or /* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */ 1 if they should be kept. */
static u8 run_target_forkserver(afl_forkserver_t *fsrv, char** argv, u8* mem, u32 len) { static u8 run_target_forkserver(afl_forkserver_t* fsrv, char** argv, u8* mem,
u32 len) {
static struct itimerval it; static struct itimerval it;
static u32 prev_timed_out = 0; static u32 prev_timed_out = 0;
@ -476,7 +477,8 @@ static void run_target(afl_forkserver_t *fsrv, char** argv) {
if (!quiet_mode) SAYF(cRST "-- Program output ends --\n"); if (!quiet_mode) SAYF(cRST "-- Program output ends --\n");
if (!fsrv->child_timed_out && !stop_soon && WIFSIGNALED(status)) child_crashed = 1; if (!fsrv->child_timed_out && !stop_soon && WIFSIGNALED(status))
child_crashed = 1;
if (!quiet_mode) { if (!quiet_mode) {
@ -693,7 +695,8 @@ static void find_binary(afl_forkserver_t *fsrv, u8* fname) {
} }
if (!fsrv->target_path) FATAL("Program '%s' not found or not executable", fname); if (!fsrv->target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -912,9 +915,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
} else } else
@ -985,7 +990,8 @@ int main(int argc, char** argv, char** envp) {
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue; if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
#endif #endif
snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file, dir_ent->d_name); snprintf(outfile, sizeof(outfile), "%s/%s", fsrv->out_file,
dir_ent->d_name);
if (read_file(infile)) { if (read_file(infile)) {

View File

@ -403,7 +403,8 @@ static void init_forkserver(char **argv) {
/* Execute target application. Returns 0 if the changes are a dud, or /* Execute target application. Returns 0 if the changes are a dud, or
1 if they should be kept. */ 1 if they should be kept. */
static u8 run_target(afl_forkserver_t *fsrv, char** argv, u8* mem, u32 len, u8 first_run) { static u8 run_target(afl_forkserver_t* fsrv, char** argv, u8* mem, u32 len,
u8 first_run) {
static struct itimerval it; static struct itimerval it;
static u32 prev_timed_out = 0; static u32 prev_timed_out = 0;
@ -1070,7 +1071,8 @@ static void find_binary(afl_forkserver_t *fsrv, u8* fname) {
} }
if (!fsrv->target_path) FATAL("Program '%s' not found or not executable", fname); if (!fsrv->target_path)
FATAL("Program '%s' not found or not executable", fname);
} }
@ -1275,9 +1277,11 @@ int main(int argc, char** argv, char** envp) {
if (qemu_mode) { if (qemu_mode) {
if (use_wine) if (use_wine)
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
else else
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
argv + optind);
} else } else
@ -1344,7 +1348,6 @@ int main(int argc, char** argv, char** envp) {
OKF("We're done here. Have a nice day!\n"); OKF("We're done here. Have a nice day!\n");
afl_shm_deinit(&shm); afl_shm_deinit(&shm);
afl_fsrv_deinit(fsrv); afl_fsrv_deinit(fsrv);
free(fsrv); free(fsrv);