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

Commit

Permalink
next step for seed initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
vanhauser-thc committed Sep 25, 2020
1 parent 4e2230b commit b9edfa8
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 73 deletions.
10 changes: 5 additions & 5 deletions examples/forking-fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,18 @@ static float timeout_fbck_is_interesting(afl_feedback_t *feedback, afl_executor_
obs_channel_time_t *observer_time = time_fbck->timeout_observer;
u32 last_run_time = *observer_time->last_run_time_p;

if (last_run_time == exec_timeout) {
if (last_run_time >= exec_timeout) {

afl_input_t *input = fsrv->base.current_input->funcs.copy(fsrv->base.current_input);
if (!input) { FATAL("Error creating a copy of input"); }

afl_entry_t *new_entry = afl_entry_new(input);
afl_entry_t *new_entry = afl_entry_new(input, NULL);
new_entry->info->skip_entry = 1;

feedback->queue->base.funcs.insert(&feedback->queue->base, new_entry);
return 0.0;

}

else {
} else {

return 0.0;

Expand Down
126 changes: 89 additions & 37 deletions examples/libaflfuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ static u8 *virgin_bits;
/* The current client this process works on. We need this for our segfault handler */
static llmp_client_t *current_client = NULL;
/* Ptr to the message we're trying to fuzz right now - in case we crash... */
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;
static llmp_message_t * current_fuzz_input_msg = NULL;
static afl_queue_global_t *global_queue;
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 @@ -113,26 +114,31 @@ static afl_ret_t in_memory_fuzzer_initialize(afl_executor_t *executor) {

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

/* TODO
while(calibration_idx > 0) {
global_queue = in_memory_fuzzer->global_queue;

--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) {
fprintf(stderr, "Calibration todo %d\n", calibration_idx);
sleep(1);
while (calibration_idx > 0) {

if (afl_stage_run(stage, queue_entry->input) != AFL_RET_SUCCESS) {
--calibration_idx;
fprintf(stderr, "Seed %u\n", calibration_idx);
afl_entry_t *queue_entry = in_memory_fuzzer->global_queue->base.funcs.get_queue_entry(
(afl_queue_t *)in_memory_fuzzer->global_queue, calibration_idx);
if (queue_entry && !queue_entry->info->skip_entry) {

WARNF("Queue entry %d misbehaved, disabling...", calibration_idx);
queue_entry->skip_entry = true;
fprintf(stderr, "Seed %u testing ...\n", calibration_idx);
if (afl_stage_run(in_memory_fuzzer->stage, queue_entry->input, false) != AFL_RET_SUCCESS) {

}
WARNF("Queue entry %d misbehaved, disabling...", calibration_idx);
queue_entry->info->skip_entry = 1;

}

}

calibration_idx = -1; // we are done
*/
}

calibration_idx = -1; // we are done

return AFL_RET_SUCCESS;

Expand Down Expand Up @@ -177,6 +183,19 @@ static void handle_timeout(int sig, siginfo_t *info, void *ucontext) {

}

if (calibration_idx && global_queue) {

afl_entry_t *queue_entry = global_queue->base.funcs.get_queue_entry((afl_queue_t *)global_queue, calibration_idx);

if (queue_entry && !queue_entry->info->skip_entry) {

WARNF("Seed entry %d timed out, disabling...", calibration_idx);
queue_entry->info->skip_entry = 1;

}

}

write_cur_state(current_fuzz_input_msg);
current_fuzz_input_msg->tag = LLMP_TAG_TIMEOUT_V1;
if (!llmp_client_send(current_client, current_fuzz_input_msg)) { FATAL("Error sending timeout info!"); }
Expand Down Expand Up @@ -212,6 +231,19 @@ static void handle_crash(int sig, siginfo_t *info, void *ucontext) {

}

if (calibration_idx && global_queue) {

afl_entry_t *queue_entry = global_queue->base.funcs.get_queue_entry((afl_queue_t *)global_queue, calibration_idx);

if (queue_entry && !queue_entry->info->skip_entry) {

WARNF("Seed entry %d crashed, disabling...", calibration_idx);
queue_entry->info->skip_entry = 1;

}

}

llmp_page_t *current_out_map = shmem2page(&current_client->out_maps[current_client->out_map_count - 1]);
/* TODO: Broker should probably check for sender_dead and restart us? */
current_out_map->sender_dead = true;
Expand Down Expand Up @@ -355,12 +387,14 @@ u8 execute(afl_engine_t *engine, afl_input_t *input) {
}

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

(void)(instance);

/* Let's create an in-memory executor */
in_memory_executor_t *in_memory_executor = calloc(1, sizeof(in_memory_executor_t));
if (!in_memory_executor) { PFATAL("Unable to allocate mem."); }
if (debug) {
if (debug == 1234) { // TODO FIXME

in_memory_executor_init(in_memory_executor, debug_harness_func);

Expand Down Expand Up @@ -393,21 +427,21 @@ afl_engine_t *initialize_fuzzer(char *in_dir, char *queue_dir, int argc, char *a
coverage_feedback_queue->base.funcs.set_dirpath(&coverage_feedback_queue->base, queue_dir);

/* Global queue creation */
afl_queue_global_t *global_queue = afl_queue_global_new();
if (!global_queue) { FATAL("Error initializing global queue"); }
global_queue->funcs.add_feedback_queue(global_queue, coverage_feedback_queue);
global_queue->base.funcs.set_dirpath(&global_queue->base, queue_dir);
afl_queue_global_t *new_global_queue = afl_queue_global_new();
if (!new_global_queue) { FATAL("Error initializing global queue"); }
new_global_queue->funcs.add_feedback_queue(new_global_queue, coverage_feedback_queue);
new_global_queue->base.funcs.set_dirpath(&new_global_queue->base, queue_dir);

/* Coverage Feedback initialization */
afl_feedback_cov_t *coverage_feedback = afl_feedback_cov_new(coverage_feedback_queue, observer_covmap);
if (!coverage_feedback) { FATAL("Error initializing feedback"); }

/* Let's build an engine now */
afl_engine_t *engine = afl_engine_new(&in_memory_executor->base, NULL, global_queue);
afl_engine_t *engine = afl_engine_new(&in_memory_executor->base, NULL, new_global_queue);
if (!engine) { FATAL("Error initializing Engine"); }
engine->verbose = 1;
engine->funcs.add_feedback(engine, &coverage_feedback->base);
engine->funcs.set_global_queue(engine, global_queue);
engine->funcs.set_global_queue(engine, new_global_queue);
engine->in_dir = in_dir;
engine->funcs.execute = execute;

Expand All @@ -427,6 +461,8 @@ afl_engine_t *initialize_fuzzer(char *in_dir, char *queue_dir, int argc, char *a
if (!stage) { FATAL("Error creating fuzzing stage"); }
AFL_TRY(stage->funcs.add_mutator_to_stage(stage, &mutators_havoc->base),
{ FATAL("Error adding mutator: %s", afl_ret_stringify(err)); });
in_memory_executor->stage = stage;
in_memory_executor->global_queue = new_global_queue;

/* Now add the testcases */
/* first we want to support restarts and read the queue */
Expand Down Expand Up @@ -456,7 +492,7 @@ afl_engine_t *initialize_fuzzer(char *in_dir, char *queue_dir, int argc, char *a

input->bytes[input_len] = 0;

afl_entry_t *new_entry = afl_entry_new(input);
afl_entry_t *new_entry = afl_entry_new(input, NULL);
if (!new_entry) { FATAL("Could not create new entry"); }
engine->global_queue->base.funcs.insert(&engine->global_queue->base, new_entry);

Expand Down Expand Up @@ -633,22 +669,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;
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, state->calibration_idx);

}
if (queue_entry && !queue_entry->info->skip_entry) {

}
WARNF("Seed entry %d timed out, disabling...", state->calibration_idx);
queue_entry->info->skip_entry = 1;

}

}

*/
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 Down Expand Up @@ -679,7 +715,22 @@ 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;
if (state->calibration_idx >= 0) {

afl_entry_t *queue_entry =
global_queue->base.funcs.get_queue_entry((afl_queue_t *)global_queue, state->calibration_idx);

if (queue_entry && !queue_entry->info->skip_entry) {

WARNF("Seed entry %d crashed, disabling...", state->calibration_idx);
queue_entry->info->skip_entry = 1;

}

}

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 Down Expand Up @@ -781,7 +832,7 @@ int main(int argc, char **argv) {

for (i = 0; i < thread_count; i++) {

afl_engine_t *engine = initialize_fuzzer(in_dir, queue_dirpath, argc, argv);
afl_engine_t *engine = initialize_fuzzer(in_dir, queue_dirpath, argc, argv, thread_count);
if (!engine) { FATAL("Error initializing fuzzing engine"); }
engines[i] = engine;

Expand Down Expand Up @@ -813,6 +864,7 @@ int main(int argc, char **argv) {
- all fuzzer instances (using fork()) */
llmp_broker_launch_clientloops(llmp_broker);

global_queue = afl_queue_global_new();
OKF("%u client%s started running.", thread_count, thread_count == 1 ? "" : "s");
sleep(1);

Expand Down
6 changes: 4 additions & 2 deletions include/aflpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,20 @@ afl_ret_t fsrv_start(afl_executor_t *fsrv_executor);
/* Function ptr for the harness */
typedef afl_exit_t (*harness_function_type)(afl_executor_t *executor, u8 *, size_t);

typedef struct in_memeory_executor {
typedef struct in_memory_executor {

afl_executor_t base;
harness_function_type harness;
char ** argv; // These are to support the libfuzzer harnesses
int argc; // To support libfuzzer harnesses
afl_stage_t * stage;
afl_queue_global_t * global_queue;

} in_memory_executor_t;

afl_exit_t in_memory_run_target(afl_executor_t *executor);
u8 in_mem_executor_place_input(afl_executor_t *executor, afl_input_t *input);
void in_memory_executor_init(in_memory_executor_t *in_memeory_executor, harness_function_type harness);
void in_memory_executor_init(in_memory_executor_t *in_memory_executor, harness_function_type harness);

#endif

3 changes: 1 addition & 2 deletions include/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ struct afl_input_funcs {
struct afl_input {

u8 * bytes; // Raw input bytes
size_t len; // Length of the input field. C++ had strings, we have to make do
// with storing the lengths :/
size_t len; // Length of the input

struct afl_input_funcs funcs;

Expand Down
2 changes: 2 additions & 0 deletions include/llmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ struct llmp_broker_client_metadata {
int pid;
/* the client loop function */
llmp_clientloop_func clientloop;
/* the engine */
afl_engine_t *engine;
/* Additional data for this client loop */
void *data;

Expand Down
20 changes: 16 additions & 4 deletions include/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,20 @@ struct afl_entry_funcs {

};

typedef struct __attribute__((__packed__)) afl_entry_info {

u64 hash, exec_us;
u32 bytes_set, bits_set;
u8 trimmed, has_new_coverage, variable, skip_entry;

} afl_entry_info_t;

struct afl_entry {

afl_entry_info_t *info;
afl_input_t * input;
bool on_disk;
u8 * map;
bool on_disk, info_calloc;
char filename[FILENAME_LEN_MAX];
struct afl_queue *queue;
struct afl_entry *next;
Expand All @@ -70,10 +80,13 @@ struct afl_entry {

};

afl_ret_t afl_entry_init(afl_entry_t *, afl_input_t *);
afl_ret_t afl_entry_init(afl_entry_t *, afl_input_t *, afl_entry_info_t *);
void afl_entry_deinit(afl_entry_t *);

AFL_NEW_AND_DELETE_FOR_WITH_PARAMS(afl_entry, AFL_DECL_PARAMS(afl_input_t *input), AFL_CALL_PARAMS(input))
AFL_NEW_AND_DELETE_FOR_WITH_PARAMS(afl_entry, AFL_DECL_PARAMS(afl_input_t *input, afl_entry_info_t *info),
AFL_CALL_PARAMS(input, info))
// AFL_NEW_AND_DELETE_FOR_WITH_PARAMS(afl_queue_feedback, AFL_DECL_PARAMS(afl_feedback_t *feedback, char *name),
// AFL_CALL_PARAMS(feedback, name));

// Default implementations for the functions for queue_entry vtable
afl_input_t *afl_entry_get_input(afl_entry_t *entry);
Expand Down Expand Up @@ -115,7 +128,6 @@ struct afl_queue {
size_t names_id;
bool save_to_files;
bool fuzz_started;
bool skip_entry;
struct afl_queue_funcs funcs;

};
Expand Down
17 changes: 3 additions & 14 deletions src/engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ static bool afl_engine_handle_single_testcase_load(char *infile, void *data) {
this is usually not a good idea.\n"); }
*/
/* We add the corpus to the global queue */
afl_entry_t *entry = afl_entry_new(input);
afl_entry_t *entry = afl_entry_new(input, NULL);
if (!entry) {

DBG("Error allocating entry.");
Expand All @@ -228,17 +228,6 @@ static bool afl_engine_handle_single_testcase_load(char *infile, void *data) {

afl_ret_t afl_engine_load_testcases_from_dir(afl_engine_t *engine, char *dirpath) {

/* Since, this'll be the first execution, Let's start up the executor here */
if ((engine->executions == 0) && engine->executor->funcs.init_cb) {

AFL_TRY(engine->executor->funcs.init_cb(engine->executor), {

return err;

});

}

return afl_for_each_file(dirpath, afl_engine_handle_single_testcase_load, (void *)engine);

}
Expand All @@ -257,9 +246,9 @@ afl_ret_t afl_engine_handle_new_message(afl_engine_t *engine, llmp_message_t *ms
input->bytes = msg->buf;
input->len = msg->buf_len;

if (!input) { FATAL("Error creating a copy of input"); }
afl_entry_info_t *info_ptr = (afl_entry_info_t *)((u8 *)(msg->buf + msg->buf_len));

afl_entry_t *new_entry = afl_entry_new(input);
afl_entry_t *new_entry = afl_entry_new(input, info_ptr);

/* Users can experiment here, adding entries to different queues based on
* the message tag. Right now, let's just add it to all queues*/
Expand Down
Loading

0 comments on commit b9edfa8

Please sign in to comment.