diff options
Diffstat (limited to 'src/afl-forkserver.c')
-rw-r--r-- | src/afl-forkserver.c | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index c2d552cd..0037d2d5 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -42,6 +42,7 @@ #include <errno.h> #include <signal.h> #include <fcntl.h> +#include <limits.h> #include <sys/time.h> #include <sys/wait.h> #include <sys/resource.h> @@ -126,7 +127,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->last_run_timed_out = 0; fsrv_to->init_child_func = from->init_child_func; - // Note: do not copy ->add_extra_func + // Note: do not copy ->add_extra_func or ->persistent_record* list_append(&fsrv_list, fsrv_to); @@ -364,6 +365,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the fork server..."); } +#ifdef AFL_PERSISTENT_RECORD + if (unlikely(fsrv->persistent_record)) { + + fsrv->persistent_record_data = + (u8 **)ck_alloc(fsrv->persistent_record * sizeof(u8 *)); + fsrv->persistent_record_len = + (u32 *)ck_alloc(fsrv->persistent_record * sizeof(u32)); + + if (!fsrv->persistent_record_data || !fsrv->persistent_record_len) { + + FATAL("Unable to allocate memory for persistent replay."); + + } + + } + +#endif + if (fsrv->use_fauxsrv) { /* TODO: Come up with some nice way to initialize this all */ @@ -1032,6 +1051,32 @@ 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 AFL_PERSISTENT_RECORD + if (unlikely(fsrv->persistent_record)) { + + fsrv->persistent_record_len[fsrv->persistent_record_idx] = len; + fsrv->persistent_record_data[fsrv->persistent_record_idx] = afl_realloc( + (void **)&fsrv->persistent_record_data[fsrv->persistent_record_idx], + len); + + if (unlikely(!fsrv->persistent_record_data[fsrv->persistent_record_idx])) { + + FATAL("allocating replay memory failed."); + + } + + memcpy(fsrv->persistent_record_data[fsrv->persistent_record_idx], buf, len); + + if (unlikely(++fsrv->persistent_record_idx >= fsrv->persistent_record)) { + + fsrv->persistent_record_idx = 0; + + } + + } + +#endif + if (likely(fsrv->use_shmem_fuzz && fsrv->shmem_fuzz)) { if (unlikely(len > MAX_FILE)) len = MAX_FILE; @@ -1146,6 +1191,26 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } +#ifdef AFL_PERSISTENT_RECORD + // end of persistent loop? + if (unlikely(fsrv->persistent_record && + fsrv->persistent_record_pid != fsrv->child_pid)) { + + fsrv->persistent_record_pid = fsrv->child_pid; + u32 idx, val; + if (unlikely(!fsrv->persistent_record_idx)) + idx = fsrv->persistent_record - 1; + else + idx = fsrv->persistent_record_idx - 1; + val = fsrv->persistent_record_len[idx]; + memset((void *)fsrv->persistent_record_len, 0, + fsrv->persistent_record * sizeof(u32)); + fsrv->persistent_record_len[idx] = val; + + } + +#endif + if (fsrv->child_pid <= 0) { if (*stop_soon_p) { return 0; } @@ -1244,6 +1309,39 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, (fsrv->uses_crash_exitcode && WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { +#ifdef AFL_PERSISTENT_RECORD + if (unlikely(fsrv->persistent_record)) { + + char fn[PATH_MAX]; + u32 i, writecnt = 0; + for (i = 0; i < fsrv->persistent_record; ++i) { + + u32 entry = (i + fsrv->persistent_record_idx) % fsrv->persistent_record; + u8 *data = fsrv->persistent_record_data[entry]; + u32 len = fsrv->persistent_record_len[entry]; + if (likely(len && data)) { + + snprintf(fn, sizeof(fn), "%s/RECORD:%06u,cnt:%06u", + fsrv->persistent_record_dir, fsrv->persistent_record_cnt, + writecnt++); + int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644); + if (fd >= 0) { + + ck_write(fd, data, len, fn); + close(fd); + + } + + } + + } + + ++fsrv->persistent_record_cnt; + + } + +#endif + /* For a proper crash, set last_kill_signal to WTERMSIG, else set it to 0 */ fsrv->last_kill_signal = WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0; |