Skip to content
This repository has been archived by the owner on Apr 30, 2021. It is now read-only.

Commit

Permalink
prepare for mini calibration in libaflfuzzer
Browse files Browse the repository at this point in the history
  • Loading branch information
vanhauser-thc committed Sep 23, 2020
1 parent d36ee6a commit f238306
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 27 deletions.
71 changes: 61 additions & 10 deletions examples/libaflfuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static llmp_message_t *current_fuzz_input_msg = NULL;
static afl_input_t * current_input = NULL;
static int debug = 0;
static char * queue_dirpath;
static ssize_t calibration_idx = -1;

typedef struct cur_state {

Expand Down Expand Up @@ -105,13 +106,34 @@ afl_exit_t debug_harness_func(afl_executor_t *executor, u8 *input, size_t len) {

}

/* Initializer: LLVMFuzzerInitialize */
/* Initializer: run initial seeds and run LLVMFuzzerInitialize */
static afl_ret_t in_memory_fuzzer_initialize(afl_executor_t *executor) {

in_memory_executor_t *in_memory_fuzzer = (in_memory_executor_t *)executor;

if (LLVMFuzzerInitialize) { LLVMFuzzerInitialize(&in_memory_fuzzer->argc, &in_memory_fuzzer->argv); }

/* TODO
while(calibration_idx > 0) {
--calibration_idx;
afl_entry_t *queue_entry = global_queue->base.funcs.get_queue_entry((afl_queue_t *)global_queue, calibration_idx);
if (queue_entry && queue_entry->skip_entry == false) {
if (afl_stage_run(stage, queue_entry->input) != AFL_RET_SUCCESS) {
WARNF("Queue entry %d misbehaved, disabling...", calibration_idx);
queue_entry->skip_entry = true;
}
}
}
calibration_idx = -1; // we are done
*/

return AFL_RET_SUCCESS;

}
Expand All @@ -129,6 +151,7 @@ void write_cur_state(llmp_message_t *out_msg) {
state->map_size = __afl_map_size;
memcpy(state->payload, virgin_bits, state->map_size);
state->current_input_len = current_input->len;
state->calibration_idx = calibration_idx;
memcpy(state->payload + state->map_size, current_input->bytes, current_input->len);

}
Expand Down Expand Up @@ -322,8 +345,7 @@ u8 execute(afl_engine_t *engine, afl_input_t *input) {
default: {

/* TODO: We'll never reach this, actually... */
if (afl_input_dump_to_crashfile(executor->current_input, queue_dirpath) == AFL_RET_SUCCESS)
engine->crashes++;
if (afl_input_dump_to_crashfile(executor->current_input, queue_dirpath) == AFL_RET_SUCCESS) engine->crashes++;
return AFL_RET_WRITE_TO_CRASH;

}
Expand All @@ -332,7 +354,7 @@ u8 execute(afl_engine_t *engine, afl_input_t *input) {

}

/* This initializeds the fuzzer */
/* This initializes the fuzzer */
afl_engine_t *initialize_fuzzer(char *in_dir, char *queue_dir, int argc, char *argv[]) {

/* Let's create an in-memory executor */
Expand Down Expand Up @@ -440,7 +462,8 @@ afl_engine_t *initialize_fuzzer(char *in_dir, char *queue_dir, int argc, char *a

}

OKF("Starting seed count: %llu", ((afl_queue_t *)engine->global_queue)->entries_count);
calibration_idx = (ssize_t)((afl_queue_t *)engine->global_queue)->entries_count;
OKF("Starting seed count: %llu", calibration_idx);

return engine;

Expand Down Expand Up @@ -478,13 +501,18 @@ void fuzzer_process_main(llmp_client_t *llmp_client, void *data) {

afl_stage_t * stage = engine->fuzz_one->stages[0];
afl_mutator_scheduled_t *mutators_havoc = (afl_mutator_scheduled_t *)stage->mutators[0];
afl_feedback_cov_t *coverage_feedback = NULL;
afl_feedback_cov_t * coverage_feedback = NULL;
for (i = 0; i < engine->feedbacks_count; i++) {

if (engine->feedbacks[i]->tag == AFL_FEEDBACK_TAG_COV) {

coverage_feedback = (afl_feedback_cov_t *)(engine->feedbacks[i]);
break;

}

}

if (!coverage_feedback) { FATAL("No coverage feedback added to engine"); }

/* The actual fuzzing */
Expand Down Expand Up @@ -605,6 +633,22 @@ bool broker_message_hook(llmp_broker_t *broker, llmp_broker_clientdata_t *client
DBG("We found a timeout...");
/* write timeout output */
state = LLMP_MSG_BUF_AS(msg, cur_state_t);
if (state->calibration_idx < calibration_idx) calibration_idx = state->calibration_idx;
/*
if (state->calibration_idx >= 0) {
afl_entry_t *queue_entry = global_queue->base.funcs.get_queue_entry((afl_queue_t *)global_queue,
calibration_idx); if (queue_entry && queue_entry->skip_entry == false) { if (afl_stage_run(stage,
queue_entry->input) != AFL_RET_SUCCESS) { WARNF("Queue entry %d misbehaved, disabling...", calibration_idx);
queue_entry->skip_entry = true;
}
}
}
*/
afl_input_t timeout_input = {0};
AFL_TRY(afl_input_init(&timeout_input),
{ FATAL("Error initializing input for crash: %s", afl_ret_stringify(err)); });
Expand All @@ -613,10 +657,13 @@ bool broker_message_hook(llmp_broker_t *broker, llmp_broker_clientdata_t *client
timeout_input.len = state->current_input_len;

if (timeout_input.len) {
if (afl_input_dump_to_timeoutfile(&timeout_input, queue_dirpath) == AFL_RET_SUCCESS)
fuzzer_stats->timeouts++;

if (afl_input_dump_to_timeoutfile(&timeout_input, queue_dirpath) == AFL_RET_SUCCESS) fuzzer_stats->timeouts++;

} else {

WARNF("Crash input has zero length, this cannot happen.");

}

broker_handle_client_restart(broker, clientdata, state);
Expand All @@ -632,6 +679,7 @@ bool broker_message_hook(llmp_broker_t *broker, llmp_broker_clientdata_t *client
DBG("We found a crash!");
/* write crash output */
state = LLMP_MSG_BUF_AS(msg, cur_state_t);
if (state->calibration_idx < calibration_idx) calibration_idx = state->calibration_idx;
afl_input_t crashing_input = {0};
AFL_TRY(afl_input_init(&crashing_input),
{ FATAL("Error initializing input for crash: %s", afl_ret_stringify(err)); });
Expand All @@ -640,10 +688,13 @@ bool broker_message_hook(llmp_broker_t *broker, llmp_broker_clientdata_t *client
crashing_input.len = state->current_input_len;

if (crashing_input.len) {
if (afl_input_dump_to_crashfile(&crashing_input, queue_dirpath) == AFL_RET_SUCCESS)
fuzzer_stats->crashes++;

if (afl_input_dump_to_crashfile(&crashing_input, queue_dirpath) == AFL_RET_SUCCESS) fuzzer_stats->crashes++;

} else {

WARNF("Crash input has zero length, this cannot happen.");

}

broker_handle_client_restart(broker, clientdata, state);
Expand Down
3 changes: 3 additions & 0 deletions include/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ struct afl_queue_funcs {

afl_entry_t *(*get)(afl_queue_t *);
afl_entry_t *(*get_next_in_queue)(afl_queue_t *, int);
afl_entry_t *(*get_queue_entry)(afl_queue_t *, u32);
afl_entry_t *(*get_queue_base)(afl_queue_t *);
size_t (*get_size)(afl_queue_t *);
char *(*get_dirpath)(afl_queue_t *);
Expand All @@ -114,6 +115,7 @@ struct afl_queue {
size_t names_id;
bool save_to_files;
bool fuzz_started;
bool skip_entry;
struct afl_queue_funcs funcs;

};
Expand All @@ -132,6 +134,7 @@ void afl_queue_set_dirpath(afl_queue_t *, char *);
void afl_queue_set_engine(afl_queue_t *queue, afl_engine_t *engine);
void afl_queue_global_set_engine(afl_queue_t *, afl_engine_t *);
afl_entry_t *afl_queue_next_base_queue(afl_queue_t *queue, int engine_id);
afl_entry_t *afl_queue_get_entry(afl_queue_t *queue, u32 entry);

AFL_NEW_AND_DELETE_FOR(afl_queue)

Expand Down
1 change: 1 addition & 0 deletions include/stage.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct afl_stage {

};

afl_ret_t afl_stage_run(afl_stage_t *, afl_input_t *, bool);
afl_ret_t afl_stage_perform(afl_stage_t *, afl_input_t *);
size_t afl_stage_get_iters(afl_stage_t *);
afl_ret_t afl_stage_init(afl_stage_t *, afl_engine_t *);
Expand Down
2 changes: 1 addition & 1 deletion src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ afl_ret_t afl_input_write_to_file(afl_input_t *input, char *fname) {

// if it already exists we will not overwrite it
if (access(fname, W_OK) == 0) return AFL_RET_FILE_DUPLICATE;

s32 fd = open(fname, O_RDWR | O_CREAT | O_EXCL, 0600);

if (fd < 0) { return AFL_RET_FILE_OPEN_ERROR; }
Expand Down
16 changes: 10 additions & 6 deletions src/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ afl_ret_t afl_queue_init(afl_queue_t *queue) {
queue->funcs.set_dirpath = afl_queue_set_dirpath;
queue->funcs.set_engine = afl_queue_set_engine;
queue->funcs.get_next_in_queue = afl_queue_next_base_queue;
queue->funcs.get_queue_entry = afl_queue_get_entry;

return AFL_RET_SUCCESS;

Expand Down Expand Up @@ -266,20 +267,23 @@ void afl_queue_set_engine(afl_queue_t *queue, afl_engine_t *engine) {

}

afl_entry_t *afl_queue_get_entry(afl_queue_t *queue, u32 entry) {

if (queue->entries_count <= entry) { return NULL; }
return queue->entries[entry];

}

afl_entry_t *afl_queue_next_base_queue(afl_queue_t *queue, int engine_id) {

if (queue->entries_count) {

afl_entry_t *current = queue->entries[queue->current];

if (engine_id != queue->engine_id) {

return current;

} // If some other engine grabs from the queue, don't update the queue's
if (engine_id != queue->engine_id) { return current; }

// If some other engine grabs from the queue, don't update the queue's
// current entry

// If we reach the end of queue, start from beginning
queue->current = (queue->current + 1) % queue->entries_count;

Expand Down
37 changes: 27 additions & 10 deletions src/stage.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,32 @@ size_t afl_stage_get_iters(afl_stage_t *stage) {

}

afl_ret_t afl_stage_run(afl_stage_t *stage, afl_input_t *input, bool overwrite) {

afl_input_t *copy;
if (!overwrite)
copy = input->funcs.copy(input);
else
copy = input;

/* Let's post process the mutated data now. */
size_t j;
for (j = 0; j < stage->mutators_count; ++j) {

afl_mutator_t *mutator = stage->mutators[j];

if (mutator->funcs.post_process) { mutator->funcs.post_process(mutator, copy); }

}

afl_ret_t ret = stage->engine->funcs.execute(stage->engine, copy);

if (!overwrite) afl_input_delete(copy);

return ret;

}

/* Perform default for fuzzing stage */
afl_ret_t afl_stage_perform(afl_stage_t *stage, afl_input_t *input) {

Expand Down Expand Up @@ -116,18 +142,9 @@ afl_ret_t afl_stage_perform(afl_stage_t *stage, afl_input_t *input) {

}

/* Let's post process the mutated data now. */
for (j = 0; j < stage->mutators_count; ++j) {

afl_mutator_t *mutator = stage->mutators[j];
afl_ret_t ret = afl_stage_run(stage, copy, true);

if (mutator->funcs.post_process) { mutator->funcs.post_process(mutator, copy); }

}

afl_ret_t ret = stage->engine->funcs.execute(stage->engine, copy);
/* Let's collect some feedback on the input now */

bool interestingness = 0.0f;

afl_feedback_t **feedbacks = stage->engine->feedbacks;
Expand Down

0 comments on commit f238306

Please sign in to comment.