diff options
author | van Hauser <vh@thc.org> | 2022-01-11 12:20:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-11 12:20:35 +0100 |
commit | 10dae419d6e3ebc38f53840c5abfe98e9c901217 (patch) | |
tree | 352576e19c8a504c40ea58dbb141056762901a69 /src/afl-forkserver.c | |
parent | 74a8f145e09d0361d8f576eb3f2e8881b6116f18 (diff) | |
parent | d2715336a54635bb6e617a2e739c0ad5fe51d28d (diff) | |
download | afl++-10dae419d6e3ebc38f53840c5abfe98e9c901217.tar.gz |
Merge pull request #1236 from AFLplusplus/dev
push to stable
Diffstat (limited to 'src/afl-forkserver.c')
-rw-r--r-- | src/afl-forkserver.c | 172 |
1 files changed, 170 insertions, 2 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index b871ea8c..eebbb7c8 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -13,7 +13,7 @@ Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Copyright 2019-2022 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -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,82 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, s32 rlen; char *ignore_autodict = getenv("AFL_NO_AUTODICT"); +#ifdef __linux__ + if (unlikely(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 ..."); } + + u32 tmp_map_size = + fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner); + fsrv->real_map_size = fsrv->map_size; + fsrv->map_size = (((tmp_map_size + 63) >> 6) << 6); + if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_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 +1172,10 @@ 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 +1192,16 @@ 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 (unlikely(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,13 +1315,80 @@ 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. */ - memset(fsrv->trace_bits, 0, fsrv->map_size); +#ifdef __linux__ + if (!fsrv->nyx_mode) { + + memset(fsrv->trace_bits, 0, fsrv->map_size); + MEM_BARRIER(); + + } +#else + memset(fsrv->trace_bits, 0, fsrv->map_size); MEM_BARRIER(); +#endif /* we have the fork server (or faux server) up and running First, tell it if the previous run timed out. */ |