diff options
Diffstat (limited to 'src/afl-forkserver.c')
-rw-r--r-- | src/afl-forkserver.c | 140 |
1 files changed, 139 insertions, 1 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b871ea8c..6604de3a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -71,6 +71,17 @@ static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { void afl_fsrv_init(afl_forkserver_t *fsrv) { +#ifdef __linux__ + fsrv->nyx_handlers = NULL; + fsrv->out_dir_path = NULL; + fsrv->nyx_mode = 0; + fsrv->nyx_parent = false; + fsrv->nyx_standalone = false; + fsrv->nyx_runner = NULL; + fsrv->nyx_id = 0xFFFFFFFF; + fsrv->nyx_bind_cpu_id = 0xFFFFFFFF; +#endif + // this structure needs default so we initialize it if this was not done // already fsrv->out_fd = -1; @@ -375,6 +386,72 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, s32 rlen; char *ignore_autodict = getenv("AFL_NO_AUTODICT"); +#ifdef __linux__ + if (fsrv->nyx_mode) { + + if(fsrv->nyx_runner != NULL){ + return; + } + + if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } + + if(fsrv->out_dir_path == NULL){ + FATAL("Nyx workdir path not found..."); + } + + char *x = alloc_printf("%s/workdir", fsrv->out_dir_path); + + if(fsrv->nyx_id == 0xFFFFFFFF){ + FATAL("Nyx ID is not set..."); + } + + if(fsrv->nyx_bind_cpu_id == 0xFFFFFFFF){ + FATAL("Nyx CPU ID is not set..."); + } + + if (fsrv->nyx_parent){ + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, !fsrv->nyx_standalone); + } + else{ + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true); + } + + if(fsrv->nyx_runner == NULL){ + FATAL("Something went wrong ..."); + } + + fsrv->map_size = fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);; + fsrv->real_map_size = fsrv->map_size; + + fsrv->trace_bits = fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner); + + fsrv->nyx_handlers->nyx_option_set_reload_mode(fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL); + fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); + + fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0); + fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); + + /* dry run */ + fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4); + switch(fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)){ + case Abort: + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + FATAL("Error: Nyx abort occured..."); + break; + case IoError: + FATAL("Error: QEMU-Nyx has died..."); + break; + case Error: + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + FATAL("Error: Nyx runtime error has occured..."); + break; + default: + break; + } + return; + } +#endif + if (!be_quiet) { ACTF("Spinning up the fork server..."); } #ifdef AFL_PERSISTENT_RECORD @@ -1085,6 +1162,11 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { fsrv->fsrv_pid = -1; fsrv->child_pid = -1; +#ifdef __linux__ + if(fsrv->nyx_mode){ + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } +#endif } /* Get the map size from the target forkserver */ @@ -1101,6 +1183,12 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { +#ifdef __linux__ + if(fsrv->nyx_mode){ + fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, buf, len); + return; + } +#endif #ifdef AFL_PERSISTENT_RECORD if (unlikely(fsrv->persistent_record)) { @@ -1214,12 +1302,62 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, u32 exec_ms; u32 write_value = fsrv->last_run_timed_out; +#ifdef __linux__ + if(fsrv->nyx_mode){ + + static uint32_t last_timeout_value = 0; + + if (last_timeout_value != timeout){ + fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, timeout/1000, (timeout%1000) * 1000); + fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); + last_timeout_value = timeout; + } + + enum NyxReturnValue ret_val = fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner); + + fsrv->total_execs++; + + switch(ret_val){ + case Normal: + return FSRV_RUN_OK; + case Crash: + case Asan: + return FSRV_RUN_CRASH; + case Timout: + return FSRV_RUN_TMOUT; + case InvalidWriteToPayload: + /* ??? */ + FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing"); + break; + case Abort: + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + FATAL("Error: Nyx abort occured..."); + case IoError: + if (*stop_soon_p){ + return 0; + } + else{ + FATAL("Error: QEMU-Nyx has died..."); + } + break; + case Error: + FATAL("Error: Nyx runtime error has occured..."); + break; + } + return FSRV_RUN_OK; + } +#endif /* After this memset, fsrv->trace_bits[] are effectively volatile, so we must prevent any earlier operations from venturing into that territory. */ +#ifdef __linux__ + if(!fsrv->nyx_mode){ + memset(fsrv->trace_bits, 0, fsrv->map_size); + } +#else memset(fsrv->trace_bits, 0, fsrv->map_size); - +#endif MEM_BARRIER(); /* we have the fork server (or faux server) up and running |