From 8fedf4998449d5b6b909a1118fc2e152e4d2e6e7 Mon Sep 17 00:00:00 2001 From: Davide Quarta Date: Tue, 23 Jan 2024 19:36:49 +0100 Subject: replay mode support --- src/afl-forkserver.c | 79 +++++++++++++++++++++++++++++++++------------------- src/afl-fuzz-init.c | 6 ++++ src/afl-fuzz.c | 2 +- 3 files changed, 57 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 3f9bfa72..f8dd783f 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1591,6 +1591,11 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, u32 exec_ms; u32 write_value = fsrv->last_run_timed_out; +#ifdef AFL_PERSISTENT_RECORD + fsrv_run_result_t retval = FSRV_RUN_OK; + char *persistent_out_fmt; +#endif + #ifdef __linux__ if (fsrv->nyx_mode) { @@ -1684,7 +1689,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } -#ifdef AFL_PERSISTENT_RECORD +#ifdef AFL_eERSISTENT_RECORD // end of persistent loop? if (unlikely(fsrv->persistent_record && fsrv->persistent_record_pid != fsrv->child_pid)) { @@ -1790,8 +1795,14 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (unlikely(fsrv->last_run_timed_out)) { fsrv->last_kill_signal = fsrv->child_kill_signal; - return FSRV_RUN_TMOUT; +#ifndef AFL_PERSISTENT_RECORD + return FSRV_RUN_TMOUT; +#else + retval = FSRV_RUN_TMOUT; + persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u"; + goto store_persistent_record; +#endif } /* Did we crash? @@ -1811,48 +1822,58 @@ 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)) { + /* 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; - char fn[PATH_MAX]; - u32 i, writecnt = 0; - for (i = 0; i < fsrv->persistent_record; ++i) { +#ifndef AFL_PERSISTENT_RECORD + return FSRV_RUN_CRASH; +#else + retval = FSRV_RUN_CRASH; + persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u"; + goto store_persistent_record; +#endif - 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) { + /* success :) */ + return FSRV_RUN_OK; + +#ifdef AFL_PERSISTENT_RECORD +store_persistent_record: + if (unlikely(retval == FSRV_RUN_CRASH || retval == FSRV_RUN_TMOUT) && + unlikely(fsrv->persistent_record)) { - ck_write(fd, data, len, fn); - close(fd); + 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), persistent_out_fmt, + 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; - return FSRV_RUN_CRASH; + ++fsrv->persistent_record_cnt; } - /* success :) */ - return FSRV_RUN_OK; + return retval; +#endif } diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 35932913..5b7dc4c1 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1915,6 +1915,9 @@ static void handle_existing_out_dir(afl_state_t *afl) { } +#ifdef AFL_PERSISTENT_RECORD + delete_files(fn, RECORD_PREFIX); +#endif if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); @@ -1947,6 +1950,9 @@ static void handle_existing_out_dir(afl_state_t *afl) { } +#ifdef AFL_PERSISTENT_RECORD + delete_files(fn, RECORD_PREFIX); +#endif if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 17949fd7..40c30472 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2163,7 +2163,7 @@ int main(int argc, char **argv_orig, char **envp) { } - afl->fsrv.persistent_record_dir = alloc_printf("%s/crashes", afl->out_dir); + afl->fsrv.persistent_record_dir = alloc_printf("%s", afl->out_dir); } -- cgit v1.2.3 From 4d493452a45655073d1b7b1dfe4ad04772b3c2b8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Jan 2024 17:00:53 +0100 Subject: tmp --- src/afl-cc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 174b3783..4f6745ed 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1103,12 +1103,18 @@ static void instrument_opt_mode_exclude(aflcc_state_t *aflcc) { } - if (aflcc->instrument_opt_mode && aflcc->compiler_mode != LLVM) + fprintf(stderr, "X %u %u\n", aflcc->compiler_mode, LTO); + + if (aflcc->instrument_opt_mode && aflcc->compiler_mode != LLVM && + !((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER) && + aflcc->compiler_mode == LTO)) FATAL("CTX, CALLER and NGRAM can only be used in LLVM mode"); if (aflcc->instrument_opt_mode && aflcc->instrument_opt_mode != INSTRUMENT_OPT_CODECOV && - aflcc->instrument_mode != INSTRUMENT_CLASSIC) + aflcc->instrument_mode != INSTRUMENT_CLASSIC && + !(aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER && + aflcc->compiler_mode == LTO)) FATAL( "CALLER, CTX and NGRAM instrumentation options can only be used with " "the LLVM CLASSIC instrumentation mode."); -- cgit v1.2.3 From bd13d32437ebf0c1f7304dc4c8f9797dc4cce7fb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 2 Feb 2024 09:54:24 +0100 Subject: final touches --- src/afl-cc.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 4f6745ed..fd466541 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1103,8 +1103,6 @@ static void instrument_opt_mode_exclude(aflcc_state_t *aflcc) { } - fprintf(stderr, "X %u %u\n", aflcc->compiler_mode, LTO); - if (aflcc->instrument_opt_mode && aflcc->compiler_mode != LLVM && !((aflcc->instrument_opt_mode & INSTRUMENT_OPT_CALLER) && aflcc->compiler_mode == LTO)) -- cgit v1.2.3 From d85722a4f6329940545dd66bf16718d591fca681 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 3 Feb 2024 13:31:31 +0100 Subject: deterministic fuzzing and -z --- src/afl-fuzz-state.c | 2 +- src/afl-fuzz.c | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 4467cae8..ae327117 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -102,7 +102,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->stats_update_freq = 1; afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000; afl->stats_avg_exec = 0; - afl->skip_deterministic = 1; + afl->skip_deterministic = 0; afl->sync_time = SYNC_TIME; afl->cmplog_lvl = 2; afl->min_length = 1; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 12d67fe7..b556b4b6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -170,7 +170,6 @@ static void usage(u8 *argv0, int more_help) { " -g minlength - set min length of generated fuzz input (default: 1)\n" " -G maxlength - set max length of generated fuzz input (default: " "%lu)\n" - " -D - enable (a new) effective deterministic fuzzing\n" " -L minutes - use MOpt(imize) mode and set the time limit for " "entering the\n" " pacemaker mode (minutes of no new finds). 0 = " @@ -213,7 +212,8 @@ static void usage(u8 *argv0, int more_help) { " -F path - sync to a foreign fuzzer queue directory (requires " "-M, can\n" " be specified up to %u times)\n" - // " -d - skip deterministic fuzzing in -M mode\n" + " -z - skip the enhanced deterministic fuzzing\n" + " (note that the old -d and -D flags are ignored.)\n" " -T text - text banner to show on the screen\n" " -I command - execute this command/script when a new crash is " "found\n" @@ -955,20 +955,15 @@ int main(int argc, char **argv_orig, char **envp) { break; - case 'D': /* partial deterministic */ + case 'd': + case 'D': /* old deterministic */ - afl->skip_deterministic = 0; + WARNF("Parameters -d and -D are deprecated, a new enhanced deterministic fuzzing is active by default, to disable it use -z"); break; - case 'd': /* no deterministic */ + case 'z': /* no deterministic */ - // this is the default and currently a lot of infrastructure enforces - // it (e.g. clusterfuzz, fuzzbench) based on that this feature - // originally was bad performance wise. We now have a better - // implementation, hence if it is activated, we do not want to - // deactivate it by such setups. - - // afl->skip_deterministic = 1; + afl->skip_deterministic = 1; break; case 'B': /* load bitmap */ -- cgit v1.2.3 From dc151caa1839162e470e003837e630db6d5d543e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 3 Feb 2024 15:53:54 +0100 Subject: add lto caller instrumentation --- src/afl-cc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 7d33b9f5..4d586ce8 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -2921,11 +2921,12 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) { " AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding " "functions\n" " into this file (LTO mode)\n" + " AFL_LLVM_LTO_CALLER: activate CALLER/CTX instrumentation\n" + " AFL_LLVM_LTO_CALLER_DEPTH: skip how many empty functions\n" " AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " "global var\n" " AFL_LLVM_LTO_STARTID: from which ID to start counting from for " - "a " - "bb\n" + "a bb\n" " AFL_REAL_LD: use this lld linker instead of the compiled in " "path\n" " AFL_LLVM_LTO_SKIPINIT: don't inject initialization code " -- cgit v1.2.3 From 9fab7e892d4e2ba09305aac40392a4df598464c9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 3 Feb 2024 16:48:38 +0100 Subject: new forkserver - server part --- src/afl-forkserver.c | 368 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 267 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 0a77d61c..1f796e53 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -389,7 +389,7 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) { while (1) { uint32_t was_killed; - int status; + u32 status; /* Wait for parent by reading from the pipe. Exit if read fails. */ @@ -524,7 +524,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, volatile u8 *stop_soon_p, u8 debug_child_output) { int st_pipe[2], ctl_pipe[2]; - s32 status; + u32 status; s32 rlen; char *ignore_autodict = getenv("AFL_NO_AUTODICT"); @@ -1017,69 +1017,95 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (rlen == 4) { + /* + * The new fork server model works like this: + * Client: sends "AFLx" in little endian, with x being the forkserver + * protocol version. + * Server: replies with XOR of the message or exits with an error if it + * is not a supported version. + * Client: sends 32 bit of options and then sends all parameters of + * the options, one after another, increasing by option number. + * Ends with "AFLx". + * After the initial protocol version confirmation the server does not + * send any data anymore - except a future option requires this. + */ + if (status >= 0x41464c00 && status <= 0x41464cff) { - FATAL( - "Target uses the new forkserver model, you need to switch to a newer " - "afl-fuzz too!"); + u32 version = status - 0x41464c00; - } + if (!version) { - if (!be_quiet) { OKF("All right - fork server is up."); } + FATAL( + "Fork server version is not assigned, this should not happen. " + "Recompile target."); - if (getenv("AFL_DEBUG")) { + } else if (version < FS_NEW_VERSION_MIN || version > FS_NEW_VERSION_MAX) { - ACTF("Extended forkserver functions received (%08x).", status); + FATAL( + "Fork server version is not not supported. Recompile the target."); - } + } - if ((status & FS_OPT_ERROR) == FS_OPT_ERROR) - report_error_and_exit(FS_OPT_GET_ERROR(status)); + status ^= 0xffffffff; + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { - if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { + FATAL("Writing to forkserver failed."); - // workaround for recent AFL++ versions - if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND) - status = (status & 0xf0ffffff); + } - if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) { + if (!be_quiet) { - if (fsrv->qemu_mode || fsrv->frida_mode) { + OKF("All right - new fork server model v%u is up.", version); - report_error_and_exit(FS_ERROR_OLD_CMPLOG_QEMU); + } - } else { + rlen = read(fsrv->fsrv_st_fd, &status, 4); - report_error_and_exit(FS_ERROR_OLD_CMPLOG); + if (getenv("AFL_DEBUG")) { - } + ACTF("Forkserver options received: (%08x)", status); } - if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) { + if ((status & FS_NEW_OPT_MAPSIZE)) { - fsrv->snapshot = 1; - if (!be_quiet) { ACTF("Using SNAPSHOT feature."); } + u32 tmp_map_size; + rlen = read(fsrv->fsrv_st_fd, &tmp_map_size, 4); - } + if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; } - if ((status & FS_OPT_SHDMEM_FUZZ) == FS_OPT_SHDMEM_FUZZ) { + fsrv->real_map_size = tmp_map_size; - if (fsrv->support_shmem_fuzz) { + if (tmp_map_size % 64) { - fsrv->use_shmem_fuzz = 1; - if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); } + tmp_map_size = (((tmp_map_size + 63) >> 6) << 6); + + } - if ((status & FS_OPT_AUTODICT) == 0 || ignore_autodict) { + if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); } + if (tmp_map_size > fsrv->map_size) { - u32 send_status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); - if (write(fsrv->fsrv_ctl_fd, &send_status, 4) != 4) { + FATAL( + "Target's coverage map size of %u is larger than the one this " + "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and " + "restart " + " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile " + "afl-fuzz", + tmp_map_size, fsrv->map_size, tmp_map_size); - FATAL("Writing to forkserver failed."); + } - } + fsrv->map_size = tmp_map_size; - } + } + + if ((status & FS_NEW_OPT_SHDMEM_FUZZ)) { + + if (fsrv->support_shmem_fuzz) { + + fsrv->use_shmem_fuzz = 1; + if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); } } else { @@ -1091,134 +1117,274 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) { + if ((status & FS_NEW_OPT_AUTODICT)) { - u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status); + u32 dict_size; + if (read(fsrv->fsrv_st_fd, &dict_size, 4) != 4) { - if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; } + FATAL("Reading from forkserver failed."); - fsrv->real_map_size = tmp_map_size; + } - if (tmp_map_size % 64) { + if (dict_size < 2 || dict_size > 0xffffff) { - tmp_map_size = (((tmp_map_size + 63) >> 6) << 6); + FATAL("Dictionary has an illegal size: %d", dict_size); } - if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); } - if (tmp_map_size > fsrv->map_size) { + u32 offset = 0, count = 0; + u8 *dict = ck_alloc(dict_size); + if (dict == NULL) { - FATAL( - "Target's coverage map size of %u is larger than the one this " - "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart " - " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile " - "afl-fuzz", - tmp_map_size, fsrv->map_size, tmp_map_size); + FATAL("Could not allocate %u bytes of autodictionary memory", + dict_size); } - fsrv->map_size = tmp_map_size; + while (dict_size != 0) { + + rlen = read(fsrv->fsrv_st_fd, dict + offset, dict_size); + if (rlen > 0) { + + dict_size -= rlen; + offset += rlen; + + } else { + + FATAL( + "Reading autodictionary fail at position %u with %u bytes " + "left.", + offset, dict_size); + + } + + } + + offset = 0; + while (offset < dict_size && (u8)dict[offset] + offset < dict_size) { + + fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, + (u8)dict[offset]); + offset += (1 + dict[offset]); + count++; + + } + + if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); } + ck_free(dict); } - if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { + u32 status2; + rlen = read(fsrv->fsrv_st_fd, &status2, 4); - if (!ignore_autodict) { + if (status2 != status) { FATAL("Error in forkserver communication"); } - if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { + } else { - // this is not afl-fuzz - or it is cmplog - we deny and return - if (fsrv->use_shmem_fuzz) { + WARNF( + "Old fork server model is used by the target, this still works " + "though."); - status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); + if (!be_quiet) { OKF("All right - old fork server is up."); } - } else { + if (getenv("AFL_DEBUG")) { - status = (FS_OPT_ENABLED); + ACTF("Extended forkserver functions received (%08x).", status); - } + } - if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { + if ((status & FS_OPT_ERROR) == FS_OPT_ERROR) + report_error_and_exit(FS_OPT_GET_ERROR(status)); - FATAL("Writing to forkserver failed."); + if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { - } + // workaround for recent AFL++ versions + if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == + FS_OPT_OLD_AFLPP_WORKAROUND) + status = (status & 0xf0ffffff); + + if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) { + + if (fsrv->qemu_mode || fsrv->frida_mode) { + + report_error_and_exit(FS_ERROR_OLD_CMPLOG_QEMU); + + } else { - return; + report_error_and_exit(FS_ERROR_OLD_CMPLOG); } - if (!be_quiet) { ACTF("Using AUTODICT feature."); } + } + + if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) { + + fsrv->snapshot = 1; + if (!be_quiet) { ACTF("Using SNAPSHOT feature."); } + + } + + if ((status & FS_OPT_SHDMEM_FUZZ) == FS_OPT_SHDMEM_FUZZ) { + + if (fsrv->support_shmem_fuzz) { + + fsrv->use_shmem_fuzz = 1; + if (!be_quiet) { ACTF("Using SHARED MEMORY FUZZING feature."); } + + if ((status & FS_OPT_AUTODICT) == 0 || ignore_autodict) { - if (fsrv->use_shmem_fuzz) { + u32 send_status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); + if (write(fsrv->fsrv_ctl_fd, &send_status, 4) != 4) { - status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); + FATAL("Writing to forkserver failed."); + + } + + } } else { - status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); + FATAL( + "Target requested sharedmem fuzzing, but we failed to enable " + "it."); } - if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { + } - FATAL("Writing to forkserver failed."); + if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) { - } + u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status); - if (read(fsrv->fsrv_st_fd, &status, 4) != 4) { + if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; } - FATAL("Reading from forkserver failed."); + fsrv->real_map_size = tmp_map_size; + + if (tmp_map_size % 64) { + + tmp_map_size = (((tmp_map_size + 63) >> 6) << 6); } - if (status < 2 || (u32)status > 0xffffff) { + if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); } + if (tmp_map_size > fsrv->map_size) { - FATAL("Dictionary has an illegal size: %d", status); + FATAL( + "Target's coverage map size of %u is larger than the one this " + "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and " + "restart " + " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile " + "afl-fuzz", + tmp_map_size, fsrv->map_size, tmp_map_size); } - u32 offset = 0, count = 0; - u32 len = status; - u8 *dict = ck_alloc(len); - if (dict == NULL) { + fsrv->map_size = tmp_map_size; + + } - FATAL("Could not allocate %u bytes of autodictionary memory", len); + if ((status & FS_OPT_AUTODICT) == FS_OPT_AUTODICT) { - } + if (!ignore_autodict) { - while (len != 0) { + if (fsrv->add_extra_func == NULL || fsrv->afl_ptr == NULL) { - rlen = read(fsrv->fsrv_st_fd, dict + offset, len); - if (rlen > 0) { + // this is not afl-fuzz - or it is cmplog - we deny and return + if (fsrv->use_shmem_fuzz) { - len -= rlen; - offset += rlen; + status = (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ); + + } else { + + status = (FS_OPT_ENABLED); + + } + + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { + + FATAL("Writing to forkserver failed."); + + } + + return; + + } + + if (!be_quiet) { ACTF("Using AUTODICT feature."); } + + if (fsrv->use_shmem_fuzz) { + + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT | FS_OPT_SHDMEM_FUZZ); } else { - FATAL( - "Reading autodictionary fail at position %u with %u bytes " - "left.", - offset, len); + status = (FS_OPT_ENABLED | FS_OPT_AUTODICT); } - } + if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { - offset = 0; - while (offset < (u32)status && - (u8)dict[offset] + offset < (u32)status) { + FATAL("Writing to forkserver failed."); - fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, - (u8)dict[offset]); - offset += (1 + dict[offset]); - count++; + } - } + if (read(fsrv->fsrv_st_fd, &status, 4) != 4) { - if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); } - ck_free(dict); + FATAL("Reading from forkserver failed."); + + } + + if (status < 2 || (u32)status > 0xffffff) { + + FATAL("Dictionary has an illegal size: %d", status); + + } + + u32 offset = 0, count = 0; + u32 len = status; + u8 *dict = ck_alloc(len); + if (dict == NULL) { + + FATAL("Could not allocate %u bytes of autodictionary memory", + len); + + } + + while (len != 0) { + + rlen = read(fsrv->fsrv_st_fd, dict + offset, len); + if (rlen > 0) { + + len -= rlen; + offset += rlen; + + } else { + + FATAL( + "Reading autodictionary fail at position %u with %u bytes " + "left.", + offset, len); + + } + + } + + offset = 0; + while (offset < (u32)status && + (u8)dict[offset] + offset < (u32)status) { + + fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, + (u8)dict[offset]); + offset += (1 + dict[offset]); + count++; + + } + + if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); } + ck_free(dict); + + } } -- cgit v1.2.3 From 27338fcef121c7700a1e2e99cb31cb7106159293 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 3 Feb 2024 18:27:01 +0100 Subject: new forkserver - client side --- src/afl-forkserver.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 1f796e53..a3a869d7 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1030,6 +1030,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, * send any data anymore - except a future option requires this. */ + if ((status & FS_NEW_ERROR) == FS_NEW_ERROR) { + + report_error_and_exit(status & 0x0000ffff); + + } + if (status >= 0x41464c00 && status <= 0x41464cff) { u32 version = status - 0x41464c00; @@ -1047,6 +1053,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } + u32 keep = status; status ^= 0xffffffff; if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) { @@ -1064,7 +1071,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (getenv("AFL_DEBUG")) { - ACTF("Forkserver options received: (%08x)", status); + ACTF("Forkserver options received: (0x%08x)", status); } @@ -1178,7 +1185,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u32 status2; rlen = read(fsrv->fsrv_st_fd, &status2, 4); - if (status2 != status) { FATAL("Error in forkserver communication"); } + if (status2 != keep) { + + FATAL("Error in forkserver communication (%08x=>%08x)", keep, status2); + + } } else { -- cgit v1.2.3 From c77709cdd9b50832ed537dfd65d30bc7ffa79e7b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 4 Feb 2024 16:03:12 +0100 Subject: add U256/32byte support --- src/afl-forkserver.c | 10 ++++++++++ src/afl-fuzz-redqueen.c | 10 +++++----- src/afl-fuzz.c | 6 ++++-- 3 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a3a869d7..c5184639 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1105,6 +1105,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, fsrv->map_size = tmp_map_size; + } else { + + fsrv->real_map_size = fsrv->map_size = MAP_SIZE; + } if ((status & FS_NEW_OPT_SHDMEM_FUZZ)) { @@ -1208,6 +1212,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_ERROR) == FS_OPT_ERROR) report_error_and_exit(FS_OPT_GET_ERROR(status)); + if (fsrv->cmplog_binary) { + + FATAL("Target was recompiled with outdated CMPLOG, recompile it!\n"); + + } + if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { // workaround for recent AFL++ versions diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index eead7a8b..eb96de68 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -11,7 +11,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2024 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 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. @@ -2219,15 +2219,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 || - ol0 > 31 || ol1 > 31) { + if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 32 || l1 > 32 || + ol0 > 32 || ol1 > 32) { l0 = ol0 = hshape; } u8 lmax = MAX(l0, ol0); - u8 save[40]; + u8 save[80]; u32 saved_idx = idx, pre, from = 0, to = 0, i, j; u32 its_len = MIN(MIN(lmax, hshape), len - idx); its_len = MIN(its_len, taint_len); @@ -2330,7 +2330,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, u32 tob64 = 0, fromb64 = 0; u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0; - u8 xor_val[32], arith_val[32], tmp[48]; + u8 xor_val[64], arith_val[64], tmp[64]; idx = saved_idx; its_len = saved_its_len; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b556b4b6..34268113 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -956,9 +956,11 @@ int main(int argc, char **argv_orig, char **envp) { break; case 'd': - case 'D': /* old deterministic */ + case 'D': /* old deterministic */ - WARNF("Parameters -d and -D are deprecated, a new enhanced deterministic fuzzing is active by default, to disable it use -z"); + WARNF( + "Parameters -d and -D are deprecated, a new enhanced deterministic " + "fuzzing is active by default, to disable it use -z"); break; case 'z': /* no deterministic */ -- cgit v1.2.3 From 6d209ce045c651089e4e55d7bb9995b496a378c0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 4 Feb 2024 16:16:32 +0100 Subject: fix -z --- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 76577081..b6900506 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -1112,7 +1112,7 @@ void show_stats_normal(afl_state_t *afl) { } else if (likely(afl->skip_deterministic)) { - strcpy(tmp, "disabled (default, enable with -D)"); + strcpy(tmp, "disabled (-z switch used)"); } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 34268113..abb1d82a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -539,7 +539,7 @@ int main(int argc, char **argv_orig, char **envp) { // still available: HjJkKqruvwz while ((opt = getopt(argc, argv, "+a:Ab:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:" - "T:UV:WXx:YZ")) > 0) { + "T:UV:WXx:YzZ")) > 0) { switch (opt) { -- cgit v1.2.3 From 40df85d1e6fb80e9d641064e645a48b623aee681 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 5 Feb 2024 15:05:46 +0100 Subject: adjust cmplog header --- src/afl-fuzz-redqueen.c | 43 ++++++++++++-- src/hashmap.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 src/hashmap.c (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index eb96de68..bc83c9ed 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -87,6 +87,11 @@ static u32 hshape; static u64 screen_update; static u64 last_update; +// hashmap functions +void hashmap_reset(); +bool hashmap_search_and_add(uint8_t type, uint64_t key); +bool hashmap_search_and_add_ptr(uint8_t type, u8 *key); + static struct range *add_range(struct range *ranges, u32 start, u32 end) { struct range *r = ck_alloc_nozero(sizeof(struct range)); @@ -795,7 +800,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 *o_buf_64 = (u64 *)&orig_buf[idx]; u32 *o_buf_32 = (u32 *)&orig_buf[idx]; u16 *o_buf_16 = (u16 *)&orig_buf[idx]; - u8 *o_buf_8 = &orig_buf[idx]; + // u8 *o_buf_8 = &orig_buf[idx]; u32 its_len = MIN(len - idx, taint_len); @@ -836,6 +841,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // necessary for preventing heap access overflow bytes = MIN(bytes, len - idx); + if (unlikely(bytes <= 1)) { return 0; } // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (afl->cmplog_enable_transform && (lvl & LVL3)) { @@ -1266,6 +1272,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } + /* if (*status != 1) { // u8 // if (its_len >= 1) @@ -1290,6 +1297,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } + */ + } // If 'S' is set for cmplog mode then we try a scale encoding of the value. @@ -1881,6 +1890,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, hshape = SHAPE_BYTES(h->shape); + if (hshape < 2) { return 0; } + if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; @@ -1906,8 +1917,6 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, #endif - if (hshape < 2) { return 0; } - for (i = 0; i < loggeds; ++i) { struct cmp_operands *o = &afl->shm.cmp_map->log[key][i]; @@ -1945,6 +1954,16 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } + // TODO: add attribute? not sure + if (hshape <= 8 && !hashmap_search_and_add(hshape - 1, o->v0) && + !hashmap_search_and_add(hshape - 1, orig_o->v0) && + !hashmap_search_and_add(hshape - 1, o->v1) && + !hashmap_search_and_add(hshape - 1, orig_o->v1)) { + + continue; + + } + #ifdef _DEBUG fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n", orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, hshape); @@ -2615,12 +2634,13 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - memcpy(buf + idx, tmp, hlen + 1 + off); + u32 tmp_l = hlen + 1 + off; + memcpy(buf + idx, tmp, tmp_l); if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - tmp[hlen + 1 + off] = 0; + tmp[tmp_l] = 0; // fprintf(stderr, "RTN ATTEMPT idx=%u len=%u fromhex %u %s %s result // %u\n", idx, len, fromhex, tmp, repl, *status); - memcpy(buf + idx, save, hlen + 1 + off); + memcpy(buf + idx, save, tmp_l); } @@ -2755,6 +2775,15 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, fprintf(stderr, "\n"); #endif + if (hshape <= 8 && !hashmap_search_and_add_ptr(hshape - 1, o->v0) && + !hashmap_search_and_add_ptr(hshape - 1, orig_o->v0) && + !hashmap_search_and_add_ptr(hshape - 1, o->v1) && + !hashmap_search_and_add_ptr(hshape - 1, orig_o->v1)) { + + continue; + + } + t = taint; while (t->next) { @@ -3021,6 +3050,8 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { // Start insertion loop + hashmap_reset(); + u64 orig_hit_cnt, new_hit_cnt; u64 orig_execs = afl->fsrv.total_execs; orig_hit_cnt = afl->queued_items + afl->saved_crashes; diff --git a/src/hashmap.c b/src/hashmap.c new file mode 100644 index 00000000..a0a9283c --- /dev/null +++ b/src/hashmap.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include "types.h" +#define TABLE_SIZE 10007 // Use a prime number for better distribution + +typedef struct HashNode { + + uint64_t key; + struct HashNode *next; + +} HashNode; + +typedef struct HashMap { + + HashNode **table; + +} HashMap; + +static HashMap *_hashmap; + +void hashmap_reset() { + + if (unlikely(!_hashmap)) { + + _hashmap = (HashMap *)malloc(sizeof(HashMap)); + _hashmap->table = (HashNode **)malloc(sizeof(HashNode *) * TABLE_SIZE); + memset((char *)_hashmap->table, 0, sizeof(HashNode *) * TABLE_SIZE); + + } else { + + for (int i = 0; i < TABLE_SIZE; i++) { + + HashNode *node = _hashmap->table[i]; + while (node) { + + HashNode *temp = node; + node = node->next; + free(temp); + + } + + } + + memset((char *)_hashmap->table, 0, sizeof(HashNode *) * TABLE_SIZE); + + } + +} + +static inline unsigned int hash(uint64_t key) { + + return key % TABLE_SIZE; + +} + +// type must be below 8 +bool hashmap_search_and_add(uint8_t type, uint64_t key) { + + if (unlikely(type >= 8)) return false; + uint64_t val = (key & 0xf8ffffffffffffff) + (type << 56); + unsigned int index = hash(val); + HashNode *node = _hashmap->table[index]; + while (node) { + + if (node->key == val) return true; + node = node->next; + + } + + // not found so add it + node = (HashNode *)malloc(sizeof(HashNode)); + node->key = val; + node->next = _hashmap->table[index]; + _hashmap->table[index] = node; + + return false; + +} + +// type must be below 8 +bool hashmap_search_and_add_ptr(uint8_t type, u8 *key) { + + if (unlikely(type >= 8)) return false; + uint64_t key_t = 0; + memcpy(((char *)key_t) + (7 - type), key, type + 1); + return hashmap_search_and_add(type, key_t); + +} + +/* below is not used */ + +void hashmap_insert(uint64_t key) { + + unsigned int index = hash(key); + HashNode *node = (HashNode *)malloc(sizeof(HashNode)); + node->key = key; + node->next = _hashmap->table[index]; + _hashmap->table[index] = node; + +} + +bool hashmap_search(uint64_t key) { + + unsigned int index = hash(key); + HashNode *node = _hashmap->table[index]; + while (node) { + + if (node->key == key) return true; + node = node->next; + + } + + return false; + +} + +void delete(uint64_t key) { + + unsigned int index = hash(key); + HashNode *prev = NULL, *node = _hashmap->table[index]; + while (node) { + + if (node->key == key) { + + if (prev) + prev->next = node->next; + else + _hashmap->table[index] = node->next; + free(node); + return; + + } + + prev = node; + node = node->next; + + } + +} + +void freeHashMap(HashMap *map) { + + free(_hashmap->table); + free(map); + +} + -- cgit v1.2.3 From 023fc19ce04bffcbd623e27a1f2d1810c3ec0c3c Mon Sep 17 00:00:00 2001 From: Davide Quarta Date: Mon, 5 Feb 2024 18:26:46 +0100 Subject: better replay mode error handling, added replay mode documentation, code formatting --- src/afl-forkserver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index f8dd783f..36e46444 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1593,7 +1593,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, #ifdef AFL_PERSISTENT_RECORD fsrv_run_result_t retval = FSRV_RUN_OK; - char *persistent_out_fmt; + char *persistent_out_fmt; #endif #ifdef __linux__ @@ -1803,6 +1803,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u"; goto store_persistent_record; #endif + } /* Did we crash? @@ -1841,7 +1842,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, #ifdef AFL_PERSISTENT_RECORD store_persistent_record: - if (unlikely(retval == FSRV_RUN_CRASH || retval == FSRV_RUN_TMOUT) && + if (unlikely(retval == FSRV_RUN_CRASH || retval == FSRV_RUN_TMOUT) && unlikely(fsrv->persistent_record)) { char fn[PATH_MAX]; -- cgit v1.2.3 From 698f1e272b8738cd1145ed687861fa5664f14c9b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 6 Feb 2024 09:34:21 +0100 Subject: fix hashmap test --- src/afl-fuzz-redqueen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index bc83c9ed..03a25903 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1955,10 +1955,10 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } // TODO: add attribute? not sure - if (hshape <= 8 && !hashmap_search_and_add(hshape - 1, o->v0) && - !hashmap_search_and_add(hshape - 1, orig_o->v0) && - !hashmap_search_and_add(hshape - 1, o->v1) && - !hashmap_search_and_add(hshape - 1, orig_o->v1)) { + if (hshape <= 8 && hashmap_search_and_add(hshape - 1, o->v0) && + hashmap_search_and_add(hshape - 1, orig_o->v0) && + hashmap_search_and_add(hshape - 1, o->v1) && + hashmap_search_and_add(hshape - 1, orig_o->v1)) { continue; @@ -2775,10 +2775,10 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, fprintf(stderr, "\n"); #endif - if (hshape <= 8 && !hashmap_search_and_add_ptr(hshape - 1, o->v0) && - !hashmap_search_and_add_ptr(hshape - 1, orig_o->v0) && - !hashmap_search_and_add_ptr(hshape - 1, o->v1) && - !hashmap_search_and_add_ptr(hshape - 1, orig_o->v1)) { + if (hshape <= 8 && hashmap_search_and_add_ptr(hshape - 1, o->v0) && + hashmap_search_and_add_ptr(hshape - 1, orig_o->v0) && + hashmap_search_and_add_ptr(hshape - 1, o->v1) && + hashmap_search_and_add_ptr(hshape - 1, orig_o->v1)) { continue; -- cgit v1.2.3 From a7fd84e186bf0151c9495817db1a2e0173344e9e Mon Sep 17 00:00:00 2001 From: Davide Quarta Date: Tue, 6 Feb 2024 21:25:40 +0100 Subject: fix typo --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 36e46444..08368061 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1689,7 +1689,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } -#ifdef AFL_eERSISTENT_RECORD +#ifdef AFL_PERSISTENT_RECORD // end of persistent loop? if (unlikely(fsrv->persistent_record && fsrv->persistent_record_pid != fsrv->child_pid)) { -- cgit v1.2.3 From ea0ea88ed3eb7c8cdc313284a6d434dcf01d7455 Mon Sep 17 00:00:00 2001 From: Davide Quarta Date: Wed, 7 Feb 2024 12:00:01 +0100 Subject: add conditional check for persistent record mode on forkserver handling of hang/crash --- src/afl-forkserver.c | 74 +++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 08368061..6b97f737 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1796,14 +1796,19 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, fsrv->last_kill_signal = fsrv->child_kill_signal; -#ifndef AFL_PERSISTENT_RECORD - return FSRV_RUN_TMOUT; -#else - retval = FSRV_RUN_TMOUT; - persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u"; - goto store_persistent_record; +#ifdef AFL_PERSISTENT_RECORD + if (unlikely(fsrv->persistent_record)) { + + retval = FSRV_RUN_TMOUT; + persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u"; + goto store_persistent_record; + + } + #endif + return FSRV_RUN_TMOUT; + } /* Did we crash? @@ -1827,53 +1832,56 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, fsrv->last_kill_signal = WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0; -#ifndef AFL_PERSISTENT_RECORD - return FSRV_RUN_CRASH; -#else - retval = FSRV_RUN_CRASH; - persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u"; - goto store_persistent_record; +#ifdef AFL_PERSISTENT_RECORD + if (unlikely(fsrv->persistent_record)) { + + retval = FSRV_RUN_CRASH; + persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u"; + goto store_persistent_record; + + } + #endif + return FSRV_RUN_CRASH; + } /* success :) */ return FSRV_RUN_OK; #ifdef AFL_PERSISTENT_RECORD -store_persistent_record: - if (unlikely(retval == FSRV_RUN_CRASH || retval == FSRV_RUN_TMOUT) && - unlikely(fsrv->persistent_record)) { - - char fn[PATH_MAX]; - u32 i, writecnt = 0; - for (i = 0; i < fsrv->persistent_record; ++i) { +store_persistent_record: { - 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)) { + char fn[PATH_MAX]; + u32 i, writecnt = 0; + for (i = 0; i < fsrv->persistent_record; ++i) { - snprintf(fn, sizeof(fn), persistent_out_fmt, - fsrv->persistent_record_dir, fsrv->persistent_record_cnt, - writecnt++); - int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644); - if (fd >= 0) { + 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)) { - ck_write(fd, data, len, fn); - close(fd); + snprintf(fn, sizeof(fn), persistent_out_fmt, 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; - } + ++fsrv->persistent_record_cnt; + return retval; + +} + #endif } -- cgit v1.2.3 From 038fef962c3d85fe7e37fcd8717270654f927881 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Feb 2024 12:46:00 +0100 Subject: performance --- src/afl-fuzz.c | 4 ++++ src/afl-performance.c | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ea8f1423..48e32996 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -401,6 +401,10 @@ static void usage(u8 *argv0, int more_help) { SAYF("Compiled with _AFL_DOCUMENT_MUTATIONS.\n"); #endif +#ifdef _AFL_SPECIAL_PERFORMANCE + SAYF("Compiled with special performance options for this specific system, it might not work on other platforms!\n"); +#endif + SAYF("For additional help please consult %s/README.md :)\n\n", doc_path); exit(1); diff --git a/src/afl-performance.c b/src/afl-performance.c index 07c1b527..22cf4dec 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -2,9 +2,18 @@ #include "afl-fuzz.h" #include "types.h" +#ifdef _HAVE_AVX2 +#define T1HA0_AESNI_AVAILABLE 1 +#define T1HA_USE_FAST_ONESHOT_READ 1 +#define T1HA_USE_INDIRECT_FUNCTIONS 1 +#define T1HA_IA32AES_NAME XXH3_64bits +#include "t1ha0_ia32aes_b.h" +#else #define XXH_INLINE_ALL #include "xxhash.h" #undef XXH_INLINE_ALL +#endif + void rand_set_seed(afl_state_t *afl, s64 init_seed) { -- cgit v1.2.3 From c23bbddde97d81fdb27351bade8f74fe71e49c21 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Feb 2024 14:31:36 +0100 Subject: workaround for MOpt bug with -S --- src/afl-fuzz.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 48e32996..85feabe6 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1236,6 +1236,7 @@ int main(int argc, char **argv_orig, char **envp) { } + afl->old_seed_selection = 1; u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000; if ((s32)limit_time_puppet2 < afl->limit_time_puppet) { -- cgit v1.2.3 From eaf4a29930fb5a397716cb34db71f1f14530923a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Feb 2024 14:54:10 +0100 Subject: make redqueen hashmap not default --- src/afl-fuzz-redqueen.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 03a25903..3342445a 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -29,6 +29,7 @@ #include "cmplog.h" // #define _DEBUG +// #define USE_HASHMAP // #define CMPLOG_INTROSPECTION // CMP attribute enum @@ -87,10 +88,12 @@ static u32 hshape; static u64 screen_update; static u64 last_update; +#ifdef USE_HASHMAP // hashmap functions void hashmap_reset(); bool hashmap_search_and_add(uint8_t type, uint64_t key); bool hashmap_search_and_add_ptr(uint8_t type, u8 *key); +#endif static struct range *add_range(struct range *ranges, u32 start, u32 end) { @@ -1954,6 +1957,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } +#ifdef USE_HASHMAP // TODO: add attribute? not sure if (hshape <= 8 && hashmap_search_and_add(hshape - 1, o->v0) && hashmap_search_and_add(hshape - 1, orig_o->v0) && @@ -1963,6 +1967,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, continue; } +#endif #ifdef _DEBUG fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n", @@ -2775,6 +2780,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, fprintf(stderr, "\n"); #endif +#ifdef USE_HASHMAP if (hshape <= 8 && hashmap_search_and_add_ptr(hshape - 1, o->v0) && hashmap_search_and_add_ptr(hshape - 1, orig_o->v0) && hashmap_search_and_add_ptr(hshape - 1, o->v1) && @@ -2783,6 +2789,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, continue; } +#endif t = taint; while (t->next) { @@ -3050,7 +3057,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { // Start insertion loop +#ifdef USE_HASHMAP hashmap_reset(); +#endif u64 orig_hit_cnt, new_hit_cnt; u64 orig_execs = afl->fsrv.total_execs; -- cgit v1.2.3 From 369fce9c85bf3b850a7109e4604fee71f694d2cb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Feb 2024 15:13:46 +0100 Subject: code format --- src/afl-fuzz-redqueen.c | 2 ++ src/afl-fuzz.c | 4 +++- src/afl-performance.c | 17 ++++++++--------- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 3342445a..be41d6c4 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1967,6 +1967,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, continue; } + #endif #ifdef _DEBUG @@ -2789,6 +2790,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, continue; } + #endif t = taint; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7c47f060..9c89b2a1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -402,7 +402,9 @@ static void usage(u8 *argv0, int more_help) { #endif #ifdef _AFL_SPECIAL_PERFORMANCE - SAYF("Compiled with special performance options for this specific system, it might not work on other platforms!\n"); + SAYF( + "Compiled with special performance options for this specific system, it " + "might not work on other platforms!\n"); #endif SAYF("For additional help please consult %s/README.md :)\n\n", doc_path); diff --git a/src/afl-performance.c b/src/afl-performance.c index 22cf4dec..f730ca53 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -3,18 +3,17 @@ #include "types.h" #ifdef _HAVE_AVX2 -#define T1HA0_AESNI_AVAILABLE 1 -#define T1HA_USE_FAST_ONESHOT_READ 1 -#define T1HA_USE_INDIRECT_FUNCTIONS 1 -#define T1HA_IA32AES_NAME XXH3_64bits -#include "t1ha0_ia32aes_b.h" + #define T1HA0_AESNI_AVAILABLE 1 + #define T1HA_USE_FAST_ONESHOT_READ 1 + #define T1HA_USE_INDIRECT_FUNCTIONS 1 + #define T1HA_IA32AES_NAME XXH3_64bits + #include "t1ha0_ia32aes_b.h" #else -#define XXH_INLINE_ALL -#include "xxhash.h" -#undef XXH_INLINE_ALL + #define XXH_INLINE_ALL + #include "xxhash.h" + #undef XXH_INLINE_ALL #endif - void rand_set_seed(afl_state_t *afl, s64 init_seed) { afl->init_seed = init_seed; -- cgit v1.2.3 From 88e41f01c839ed5c46882222ad7e1f5c3e7d9e20 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Feb 2024 15:28:19 +0100 Subject: env fix --- src/afl-cc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 4d586ce8..3a32a0d1 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -828,7 +828,7 @@ static void instrument_mode_old_environ(aflcc_state_t *aflcc) { } if (getenv("AFL_LLVM_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX; - if (getenv("AFL_LLVM_CALLER")) + if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_LTO_CALLER") || getenv("AFL_LLVM_LTO_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER; if (getenv("AFL_LLVM_NGRAM_SIZE")) { -- cgit v1.2.3 From f2b7357ff3efedca53a7cd856469b439c2e547ef Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Feb 2024 13:09:16 +0100 Subject: fixes --- src/afl-forkserver.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 7253e6d7..1d42adf5 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1197,9 +1197,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else { - WARNF( - "Old fork server model is used by the target, this still works " - "though."); + if (!fsrv->qemu_mode && !fsrv->cs_mode +#ifdef __linux__ + && !fsrv->nyx_mode +#endif + ) { + + WARNF( + "Old fork server model is used by the target, this still works " + "though."); + + } if (!be_quiet) { OKF("All right - old fork server is up."); } -- cgit v1.2.3 From 07bc202e0ad940e0cc7c8770f69ceb32ed851384 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Feb 2024 13:51:05 +0100 Subject: fixes --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 1d42adf5..8853458a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1222,7 +1222,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (fsrv->cmplog_binary) { - FATAL("Target was recompiled with outdated CMPLOG, recompile it!\n"); + FATAL("Target was compiled with outdated CMPLOG, recompile it!\n"); } -- cgit v1.2.3 From dd8806971131fafc5563d0cd993b4a2222b3b486 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Feb 2024 13:57:45 +0100 Subject: fix --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 8853458a..508b5fa7 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1220,7 +1220,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_ERROR) == FS_OPT_ERROR) report_error_and_exit(FS_OPT_GET_ERROR(status)); - if (fsrv->cmplog_binary) { + if (fsrv->cmplog_binary && !fsrv->qemu_mode) { FATAL("Target was compiled with outdated CMPLOG, recompile it!\n"); -- cgit v1.2.3 From 6dc58750cf2b321b5cb42a2080410e6d9420548b Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Thu, 15 Feb 2024 19:19:51 -0500 Subject: issue #2001: fix passing rpath to linker on macOS Seems on macOS, `ld` does not want an `=` when specifying `-rpath`. --- src/afl-cc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 3a32a0d1..6aa0da6a 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -2379,7 +2379,11 @@ void add_runtime(aflcc_state_t *aflcc) { if (aflcc->plusplus_mode && strlen(libdir) && strncmp(libdir, "/usr", 4) && strncmp(libdir, "/lib", 4)) { +#ifdef __APPLE__ + u8 *libdir_opt = strdup("-Wl,-rpath," LLVM_LIBDIR); +#else u8 *libdir_opt = strdup("-Wl,-rpath=" LLVM_LIBDIR); +#endif insert_param(aflcc, libdir_opt); } -- cgit v1.2.3 From 98238ed7630e6a5b135f520b8511548776b1b2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Wei=C3=9F?= Date: Thu, 22 Feb 2024 15:28:55 +0100 Subject: Convert from microseconds (us) to milliseconds (ms) --- src/afl-fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9c89b2a1..30babad3 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2493,8 +2493,8 @@ int main(int argc, char **argv_orig, char **envp) { for (entry = 0; entry < afl->queued_items; ++entry) if (!afl->queue_buf[entry]->disabled) - if (afl->queue_buf[entry]->exec_us > max_ms) - max_ms = afl->queue_buf[entry]->exec_us; + if ((afl->queue_buf[entry]->exec_us/1000) > max_ms) + max_ms = afl->queue_buf[entry]->exec_us/1000; afl->fsrv.exec_tmout = max_ms; afl->timeout_given = 1; -- cgit v1.2.3 From 07e0b391260d007f9dc52329dc51887fe568f109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Wei=C3=9F?= Date: Thu, 22 Feb 2024 15:55:18 +0100 Subject: Do not circumvent sanity checks from arg parsing --- src/afl-fuzz.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 30babad3..0ddb8880 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2495,8 +2495,9 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->queue_buf[entry]->disabled) if ((afl->queue_buf[entry]->exec_us/1000) > max_ms) max_ms = afl->queue_buf[entry]->exec_us/1000; - - afl->fsrv.exec_tmout = max_ms; + + if (max_ms > afl->fsrv.exec_tmout) + afl->fsrv.exec_tmout = max_ms; afl->timeout_given = 1; } -- cgit v1.2.3 From eaedf2e62f77310fc0981c1c6d3ca573662d1522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Wei=C3=9F?= Date: Fri, 23 Feb 2024 12:52:11 +0100 Subject: Adhere to documented behavior --- src/afl-fuzz.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0ddb8880..803a1acc 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2496,8 +2496,7 @@ int main(int argc, char **argv_orig, char **envp) { if ((afl->queue_buf[entry]->exec_us/1000) > max_ms) max_ms = afl->queue_buf[entry]->exec_us/1000; - if (max_ms > afl->fsrv.exec_tmout) - afl->fsrv.exec_tmout = max_ms; + afl->fsrv.exec_tmout = max_ms; afl->timeout_given = 1; } -- cgit v1.2.3 From 01f442d81016188e847eae5320882cb1fbfa6dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Wei=C3=9F?= Date: Fri, 23 Feb 2024 12:53:20 +0100 Subject: Be specific about the unit of time --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 508b5fa7..1381236c 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1931,7 +1931,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (exec_ms > timeout) { - /* If there was no response from forkserver after timeout seconds, + /* If there was no response from forkserver after timeout milliseconds, we kill the child. The forkserver should inform us afterwards */ s32 tmp_pid = fsrv->child_pid; -- cgit v1.2.3 From fae760fc9e4c63385c24fe07e5d5c3ab077b56bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Wei=C3=9F?= Date: Fri, 23 Feb 2024 13:39:46 +0100 Subject: Add upper and lower safety margins --- src/afl-fuzz.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 803a1acc..08f716fa 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2496,6 +2496,15 @@ int main(int argc, char **argv_orig, char **envp) { if ((afl->queue_buf[entry]->exec_us/1000) > max_ms) max_ms = afl->queue_buf[entry]->exec_us/1000; + // Add 20% as a safety margin, capped to exec_tmout given in -t option + max_ms *= 1.2; + if(max_ms > afl->fsrv.exec_tmout) + max_ms = afl->fsrv.exec_tmout; + + // Ensure that there is a sensible timeout even for very fast binaries + if(max_ms < 5) + max_ms = 5; + afl->fsrv.exec_tmout = max_ms; afl->timeout_given = 1; -- cgit v1.2.3 From b2b887d04decdcdadf702c585bb1992a0a821bf1 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Thu, 22 Feb 2024 10:47:53 -0500 Subject: Issue #2007: add filename extension to /crashes files This is very helpful for code that inpects a file name extension when determining what code to run. It's also useful for applications that constrain the user to choose files by extension. --- src/afl-forkserver.c | 8 +++++--- src/afl-fuzz-bitmap.c | 34 +++++++++++++++++++++++----------- src/afl-fuzz-extras.c | 5 ++++- src/afl-fuzz-init.c | 26 ++++++++++++++++++-------- 4 files changed, 50 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 508b5fa7..0d7c19c6 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -2003,7 +2003,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (unlikely(fsrv->persistent_record)) { retval = FSRV_RUN_TMOUT; - persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u"; + persistent_out_fmt = "%s/hangs/RECORD:%06u,cnt:%06u%s%s"; goto store_persistent_record; } @@ -2039,7 +2039,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, if (unlikely(fsrv->persistent_record)) { retval = FSRV_RUN_CRASH; - persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u"; + persistent_out_fmt = "%s/crashes/RECORD:%06u,cnt:%06u%s%s"; goto store_persistent_record; } @@ -2066,7 +2066,9 @@ store_persistent_record: { if (likely(len && data)) { snprintf(fn, sizeof(fn), persistent_out_fmt, fsrv->persistent_record_dir, - fsrv->persistent_record_cnt, writecnt++); + fsrv->persistent_record_cnt, writecnt++, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fd >= 0) { diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index d056ac9f..0ad68835 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -528,14 +528,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES queue_fn = - alloc_printf("%s/queue/id:%06u,%s", afl->out_dir, afl->queued_items, + alloc_printf("%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items, describe_op(afl, new_bits + is_timeout, - NAME_MAX - strlen("id:000000,"))); + NAME_MAX - strlen("id:000000,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #else queue_fn = - alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_items); + alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_items, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); @@ -739,14 +743,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s", afl->out_dir, + snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s%s%s", afl->out_dir, afl->saved_hangs, - describe_op(afl, 0, NAME_MAX - strlen("id:000000,"))); + describe_op(afl, 0, NAME_MAX - strlen("id:000000,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #else - snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu", afl->out_dir, - afl->saved_hangs); + snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu%s%s", afl->out_dir, + afl->saved_hangs, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ @@ -792,14 +800,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s", afl->out_dir, + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s", afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, - describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,"))); + describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #else - snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir, - afl->saved_crashes, afl->fsrv.last_kill_signal); + snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir, + afl->saved_crashes, afl->fsrv.last_kill_signal, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 3b1d13f1..5735db0c 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -743,7 +743,10 @@ void save_auto(afl_state_t *afl) { for (i = 0; i < MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) { u8 *fn = - alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i); + alloc_printf("%s/queue/.state/auto_extras/auto_%06u%s%s", afl->out_dir, i, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); + s32 fd; fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 54760744..102c0f15 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1157,18 +1157,22 @@ void perform_dry_run(afl_state_t *afl) { #ifndef SIMPLE_FILES - snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s", + snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s%s", afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,") - strlen(use_name)), - use_name); + use_name, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #else - snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", + snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir, afl->saved_crashes, - afl->fsrv.last_kill_signal); + afl->fsrv.last_kill_signal, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #endif @@ -1439,7 +1443,9 @@ void pivot_inputs(afl_state_t *afl) { u32 src_id; afl->resuming_fuzz = 1; - nfn = alloc_printf("%s/queue/%s", afl->out_dir, rsl); + nfn = alloc_printf("%s/queue/%s%s%s", afl->out_dir, rsl, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); /* Since we're at it, let's also get the parent and figure out the appropriate depth for this entry. */ @@ -1479,12 +1485,16 @@ void pivot_inputs(afl_state_t *afl) { } - nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s", - afl->out_dir, id, afl->fsrv.total_execs, use_name); + nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", + afl->out_dir, id, afl->fsrv.total_execs, use_name, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #else - nfn = alloc_printf("%s/queue/id_%06u", afl->out_dir, id); + nfn = alloc_printf("%s/queue/id_%06u%s%s", afl->out_dir, id, + afl->file_extension ? "." : "", + afl->file_extension ? (const char*)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ -- cgit v1.2.3 From 335b2d4542d951b6742ca02646ab1c254f64f8f2 Mon Sep 17 00:00:00 2001 From: Martin Nyhus Date: Wed, 28 Feb 2024 22:29:55 +0100 Subject: Load autodictionary when using new forkserver Fixes a bug where the new fork server would decrement dict_size until zero then try to use it as the upper bound for the number of bytes to pass to add_extra_func, causing it to never store any of the tokens. --- src/afl-forkserver.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 1381236c..d9207d45 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1152,12 +1152,11 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - while (dict_size != 0) { + while (offset < dict_size) { - rlen = read(fsrv->fsrv_st_fd, dict + offset, dict_size); + rlen = read(fsrv->fsrv_st_fd, dict + offset, dict_size - offset); if (rlen > 0) { - dict_size -= rlen; offset += rlen; } else { @@ -1165,7 +1164,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, FATAL( "Reading autodictionary fail at position %u with %u bytes " "left.", - offset, dict_size); + offset, dict_size - offset); } -- cgit v1.2.3 From 036a79268b48a0e3e061d5e3387711f69bed8d56 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 29 Feb 2024 09:10:22 +0100 Subject: gcc cmplog fix --- src/afl-cc.c | 3 ++- src/afl-fuzz.c | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 6aa0da6a..faa46103 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -828,7 +828,8 @@ static void instrument_mode_old_environ(aflcc_state_t *aflcc) { } if (getenv("AFL_LLVM_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CTX; - if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_LTO_CALLER") || getenv("AFL_LLVM_LTO_CTX")) + if (getenv("AFL_LLVM_CALLER") || getenv("AFL_LLVM_LTO_CALLER") || + getenv("AFL_LLVM_LTO_CTX")) aflcc->instrument_opt_mode |= INSTRUMENT_OPT_CALLER; if (getenv("AFL_LLVM_NGRAM_SIZE")) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 08f716fa..443d93b0 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2493,17 +2493,15 @@ int main(int argc, char **argv_orig, char **envp) { for (entry = 0; entry < afl->queued_items; ++entry) if (!afl->queue_buf[entry]->disabled) - if ((afl->queue_buf[entry]->exec_us/1000) > max_ms) - max_ms = afl->queue_buf[entry]->exec_us/1000; - + if ((afl->queue_buf[entry]->exec_us / 1000) > max_ms) + max_ms = afl->queue_buf[entry]->exec_us / 1000; + // Add 20% as a safety margin, capped to exec_tmout given in -t option max_ms *= 1.2; - if(max_ms > afl->fsrv.exec_tmout) - max_ms = afl->fsrv.exec_tmout; - + if (max_ms > afl->fsrv.exec_tmout) max_ms = afl->fsrv.exec_tmout; + // Ensure that there is a sensible timeout even for very fast binaries - if(max_ms < 5) - max_ms = 5; + if (max_ms < 5) max_ms = 5; afl->fsrv.exec_tmout = max_ms; afl->timeout_given = 1; -- cgit v1.2.3 From 6062668679300af97248a59775cde45537601480 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 29 Feb 2024 14:31:47 +0100 Subject: fix not using autodict --- src/afl-forkserver.c | 27 ++++++++++++++++++++------- src/afl-fuzz-bitmap.c | 35 +++++++++++++++++------------------ src/afl-fuzz-extras.c | 8 ++++---- src/afl-fuzz-init.c | 47 ++++++++++++++++++++++++----------------------- 4 files changed, 65 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 4877843d..158651af 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -724,7 +724,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } /* autodict in Nyx mode */ - if (!ignore_autodict) { + if (!ignore_autodict && fsrv->add_extra_func) { char *x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); @@ -1111,7 +1111,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_NEW_OPT_SHDMEM_FUZZ)) { + if ((status & FS_NEW_OPT_SHDMEM_FUZZ) && fsrv->add_extra_func && + !ignore_autodict) { if (fsrv->support_shmem_fuzz) { @@ -1130,6 +1131,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_NEW_OPT_AUTODICT)) { + // even if we do not need the dictionary we have to read it + u32 dict_size; if (read(fsrv->fsrv_st_fd, &dict_size, 4) != 4) { @@ -1173,14 +1176,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, offset = 0; while (offset < dict_size && (u8)dict[offset] + offset < dict_size) { - fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, - (u8)dict[offset]); + if (!ignore_autodict && fsrv->add_extra_func) { + + fsrv->add_extra_func(fsrv->afl_ptr, dict + offset + 1, + (u8)dict[offset]); + count++; + + } + offset += (1 + dict[offset]); - count++; } - if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); } + if (!be_quiet && count) { + + ACTF("Loaded %u autodictionary entries", count); + + } + ck_free(dict); } @@ -2067,7 +2080,7 @@ store_persistent_record: { snprintf(fn, sizeof(fn), persistent_out_fmt, fsrv->persistent_record_dir, fsrv->persistent_record_cnt, writecnt++, afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + afl->file_extension ? (const char *)afl->file_extension : ""); int fd = open(fn, O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fd >= 0) { diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 0ad68835..d8561dde 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -527,19 +527,19 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - queue_fn = - alloc_printf("%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items, - describe_op(afl, new_bits + is_timeout, - NAME_MAX - strlen("id:000000,")), - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + queue_fn = alloc_printf( + "%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items, + describe_op(afl, new_bits + is_timeout, + NAME_MAX - strlen("id:000000,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #else - queue_fn = - alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_items, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + queue_fn = alloc_printf( + "%s/queue/id_%06u", afl->out_dir, afl->queued_items, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); @@ -747,14 +747,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { afl->saved_hangs, describe_op(afl, 0, NAME_MAX - strlen("id:000000,")), afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + afl->file_extension ? (const char *)afl->file_extension : ""); #else snprintf(fn, PATH_MAX, "%s/hangs/id_%06llu%s%s", afl->out_dir, - afl->saved_hangs, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + afl->saved_hangs, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ @@ -800,18 +799,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s", afl->out_dir, - afl->saved_crashes, afl->fsrv.last_kill_signal, + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s", + afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")), afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + afl->file_extension ? (const char *)afl->file_extension : ""); #else snprintf(fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + afl->file_extension ? (const char *)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 5735db0c..c06896ef 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -742,10 +742,10 @@ void save_auto(afl_state_t *afl) { for (i = 0; i < MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) { - u8 *fn = - alloc_printf("%s/queue/.state/auto_extras/auto_%06u%s%s", afl->out_dir, i, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + u8 *fn = alloc_printf( + "%s/queue/.state/auto_extras/auto_%06u%s%s", afl->out_dir, i, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); s32 fd; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 102c0f15..21a8ba7e 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1157,22 +1157,22 @@ void perform_dry_run(afl_state_t *afl) { #ifndef SIMPLE_FILES - snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s%s", - afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, - describe_op(afl, 0, - NAME_MAX - strlen("id:000000,sig:00,") - - strlen(use_name)), - use_name, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + snprintf( + crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s%s", + afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, + describe_op( + afl, 0, + NAME_MAX - strlen("id:000000,sig:00,") - strlen(use_name)), + use_name, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #else - snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", - afl->out_dir, afl->saved_crashes, - afl->fsrv.last_kill_signal, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + snprintf( + crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u%s%s", afl->out_dir, + afl->saved_crashes, afl->fsrv.last_kill_signal, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #endif @@ -1443,9 +1443,9 @@ void pivot_inputs(afl_state_t *afl) { u32 src_id; afl->resuming_fuzz = 1; - nfn = alloc_printf("%s/queue/%s%s%s", afl->out_dir, rsl, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + nfn = alloc_printf( + "%s/queue/%s%s%s", afl->out_dir, rsl, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); /* Since we're at it, let's also get the parent and figure out the appropriate depth for this entry. */ @@ -1485,16 +1485,17 @@ void pivot_inputs(afl_state_t *afl) { } - nfn = alloc_printf("%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", - afl->out_dir, id, afl->fsrv.total_execs, use_name, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + nfn = alloc_printf( + "%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", afl->out_dir, id, + afl->fsrv.total_execs, use_name, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #else - nfn = alloc_printf("%s/queue/id_%06u%s%s", afl->out_dir, id, - afl->file_extension ? "." : "", - afl->file_extension ? (const char*)afl->file_extension : ""); + nfn = alloc_printf( + "%s/queue/id_%06u%s%s", afl->out_dir, id, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ -- cgit v1.2.3 From 52e19d35fac636f9ea4679d402b5eaabaa74aa0a Mon Sep 17 00:00:00 2001 From: "Christian Holler (:decoder)" Date: Wed, 6 Mar 2024 10:55:53 +0100 Subject: Add optional handling of Nyx InvalidWriteToPayload event --- src/afl-forkserver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 158651af..cf5c511e 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1840,6 +1840,8 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, case Timeout: return FSRV_RUN_TMOUT; case InvalidWriteToPayload: + if (!!getenv("AFL_NYX_HANDLE_INVALID_WRITE")) { return FSRV_RUN_CRASH; } + /* ??? */ FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing"); break; -- cgit v1.2.3 From 0ea53ea5b569a151902e4a8f79a6bc48a73f074b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 6 Mar 2024 12:41:00 +0100 Subject: likely --- src/afl-forkserver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 158651af..6071407a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1873,7 +1873,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, territory. */ #ifdef __linux__ - if (!fsrv->nyx_mode) { + if (likely(!fsrv->nyx_mode)) { memset(fsrv->trace_bits, 0, fsrv->map_size); MEM_BARRIER(); -- cgit v1.2.3 From 306a917956f91a34a6a9008952616fab07c8f21a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 7 Mar 2024 12:09:22 +0100 Subject: UI fix --- src/afl-fuzz-stats.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b6900506..4f398863 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -876,6 +876,10 @@ void show_stats_normal(afl_state_t *afl) { #endif + if (banner_pad) + for (u32 i = 0; i < banner_pad; ++i) + strcat(banner, " "); + } SAYF("\n%s\n", banner); -- cgit v1.2.3 From b85174fc8d599668dd17ccdd62971a09cb9497c8 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 12 Mar 2024 04:00:19 +0100 Subject: nit --- src/afl-fuzz.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 443d93b0..99491628 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2073,6 +2073,17 @@ int main(int argc, char **argv_orig, char **envp) { } + /* Simply code if AFL_TMPDIR is used or not */ + if (!afl->afl_env.afl_tmpdir) { + + afl->tmp_dir = afl->out_dir; + + } else { + + afl->tmp_dir = afl->afl_env.afl_tmpdir; + + } + write_setup_file(afl, argc, argv); setup_cmdline_file(afl, argv + optind); @@ -2085,8 +2096,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->timeout_given) { find_timeout(afl); } // only for resumes! - if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL && - !afl->in_place_resume) { + if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) { char tmpfile[PATH_MAX]; @@ -2111,10 +2121,6 @@ int main(int argc, char **argv_orig, char **envp) { } - } else { - - afl->tmp_dir = afl->out_dir; - } /* If we don't have a file name chosen yet, use a safe default. */ @@ -3068,7 +3074,7 @@ stop_fuzzing: afl_fsrv_deinit(&afl->fsrv); /* remove tmpfile */ - if (afl->tmp_dir != NULL && !afl->in_place_resume && afl->fsrv.out_file) { + if (!afl->in_place_resume && afl->fsrv.out_file) { (void)unlink(afl->fsrv.out_file); -- cgit v1.2.3 From c9ad3acc9b69daea5e99b6ef66ed1f593331d474 Mon Sep 17 00:00:00 2001 From: gnbon Date: Wed, 13 Mar 2024 12:10:38 +0900 Subject: Add -l option for adjustable block deletion - Introduce the -l option to set min block deletion length using powers of 2 (e.g., 1, 2, 4, 8, 16, ...). - This enables a trade-off between minimization thoroughness and speed. - Adjusting del_len_limit allows for faster processing, as doubling it roughly halves the minimization time. --- src/afl-tmin.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 4e5dab41..03e70a6f 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -82,6 +82,8 @@ static u8 crash_mode, /* Crash-centric mode? */ remove_shm = 1, /* remove shmem on exit? */ debug; /* debug mode */ +static u32 del_len_limit; /* Minimum block deletion length */ + static volatile u8 stop_soon; /* Ctrl-C pressed? */ static afl_forkserver_t *fsrv; @@ -421,6 +423,7 @@ next_pass: del_len = next_pow2(in_len / TRIM_START_STEPS); stage_o_len = in_len; + if (!del_len_limit) { del_len_limit = 1; } ACTF(cBRI "Stage #1: " cRST "Removing blocks of data..."); @@ -480,7 +483,7 @@ next_del_blksize: } - if (del_len > 1 && in_len >= 1) { + if (del_len > del_len_limit && in_len >= 1) { del_len /= 2; goto next_del_blksize; @@ -796,8 +799,9 @@ static void usage(u8 *argv0) { "Minimization settings:\n" " -e - solve for edge coverage only, ignore hit counts\n" - " -x - treat non-zero exit codes as crashes\n\n" - " -H - minimize a hang (hang mode)\n" + " -l bytes - set minimum block deletion length to speed up minimization\n" + " -x - treat non-zero exit codes as crashes\n" + " -H - minimize a hang (hang mode)\n\n" "For additional tips, please consult %s/README.md.\n\n" @@ -829,8 +833,9 @@ static void usage(u8 *argv0) { int main(int argc, char **argv_orig, char **envp) { - s32 opt; - u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; + s32 opt; + u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0, + del_limit_given = 0; char **use_argv; char **argv = argv_cpy_dup(argc, argv_orig); @@ -846,7 +851,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:l:B:xeAOQUWXYHh")) > 0) { switch (opt) { @@ -1055,6 +1060,24 @@ int main(int argc, char **argv_orig, char **envp) { read_bitmap(optarg, mask_bitmap, map_size); break; + case 'l': + if (del_limit_given) { FATAL("Multiple -l options not supported"); } + del_limit_given = 1; + + if (!optarg) { FATAL("Wrong usage of -l"); } + + if (optarg[0] == '-') { FATAL("Dangerously low value of -l"); } + + del_len_limit = atoi(optarg); + + if (del_len_limit < 1 || del_len_limit >= TMIN_MAX_FILE) { + + FATAL("Value of -l out of range between 1 and TMIN_MAX_FILE"); + + } + + break; + case 'h': usage(argv[0]); return -1; -- cgit v1.2.3 From 1860f6e594883965f7b630a65d5a77006f284aa1 Mon Sep 17 00:00:00 2001 From: gnbon Date: Thu, 14 Mar 2024 11:00:59 +0900 Subject: Fix invalid range for del_len_limit --- src/afl-tmin.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 03e70a6f..994174ed 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -82,7 +82,7 @@ static u8 crash_mode, /* Crash-centric mode? */ remove_shm = 1, /* remove shmem on exit? */ debug; /* debug mode */ -static u32 del_len_limit; /* Minimum block deletion length */ +static u32 del_len_limit = 1; /* Minimum block deletion length */ static volatile u8 stop_soon; /* Ctrl-C pressed? */ @@ -423,7 +423,6 @@ next_pass: del_len = next_pow2(in_len / TRIM_START_STEPS); stage_o_len = in_len; - if (!del_len_limit) { del_len_limit = 1; } ACTF(cBRI "Stage #1: " cRST "Removing blocks of data..."); @@ -1070,7 +1069,7 @@ int main(int argc, char **argv_orig, char **envp) { del_len_limit = atoi(optarg); - if (del_len_limit < 1 || del_len_limit >= TMIN_MAX_FILE) { + if (del_len_limit < 1 || del_len_limit > TMIN_MAX_FILE) { FATAL("Value of -l out of range between 1 and TMIN_MAX_FILE"); -- cgit v1.2.3 From 5ffc8c70761f97fbaffa3a98a6c472d35930c7b2 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Sat, 30 Mar 2024 11:26:38 +0300 Subject: src: fix calculation of fuzzing time in statistics When the computer is suspended during a fuzzing session, the time spent in suspended state is counted as a "run time" on a statistics screen. The time returned by `gettimeofday(2)` is affected by discontinuous jumps in the system time. It is better using `clock_gettime(2)`. The patch replace `gettimeofday` with `clock_gettime` [1]. `clock_gettime` uses a CLOCK_MONOTONIC_COARSE clock type, it is faster than CLOCK_MONOTONIC, but still has resolution (~1ms) that is adequate for our purposes. However, CLOCK_MONOTONIC_COARSE is a Linux-specific clock variant, so on macOS it is replaced with CLOCK_MONOTONIC, and with CLOCK_MONOTONIC_FAST on FreeBSD [2]. Closes #1241 1. https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_gettime.html 2. https://man.freebsd.org/cgi/man.cgi?query=clock_gettime --- src/afl-common.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 87003b03..53524e96 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -34,6 +34,7 @@ #endif #include #include +#include #include #include @@ -58,6 +59,26 @@ u8 last_intr = 0; #define AFL_PATH "/usr/local/lib/afl/" #endif +/* - Some BSD (i.e.: FreeBSD) offer the FAST clock source as + * equivalent to Linux COARSE clock source. Aliasing COARSE to + * FAST on such systems when COARSE is not already defined. + * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type. + */ +#if defined (OS_DARWIN) || defined (OS_SUNOS) +# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC +#elif defined (OS_FREEBSD) +# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST +#endif + +/* Convert seconds to milliseconds. */ +#define SEC_TO_MS(sec) ((sec)*1000) +/* Convert seconds to microseconds. */ +#define SEC_TO_US(sec) ((sec)*1000000) +/* Convert nanoseconds to milliseconds. */ +#define NS_TO_MS(ns) ((ns)/1000000) +/* Convert nanoseconds to microseconds. */ +#define NS_TO_US(ns) ((ns)/1000) + void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { @@ -973,27 +994,27 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) { /* Get unix time in milliseconds */ inline u64 get_cur_time(void) { + struct timespec ts; + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + if (rc == -1) { + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", + errno, strerror(errno)); + } - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000); - + return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec); } /* Get unix time in microseconds */ u64 get_cur_time_us(void) { + struct timespec ts; + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + if (rc == -1) { + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", + errno, strerror(errno)); + } - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv, &tz); - - return (tv.tv_sec * 1000000ULL) + tv.tv_usec; - + return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec); } /* Describe integer. The buf should be -- cgit v1.2.3 From f7ea0f569fa57e22548c1dc8eaba2903213e496e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 5 Apr 2024 14:52:53 +0200 Subject: fix aflpp custom mutator + standalone tool --- src/afl-fuzz-state.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ae327117..c61f00bd 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -28,10 +28,6 @@ #include "afl-fuzz.h" #include "envs.h" -s8 interesting_8[] = {INTERESTING_8}; -s16 interesting_16[] = {INTERESTING_8, INTERESTING_16}; -s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32}; - char *power_names[POWER_SCHEDULES_NUM] = {"explore", "mmopt", "exploit", "fast", "coe", "lin", "quad", "rare", "seek"}; -- cgit v1.2.3 From 45603367bfb71948f56715ac88e34c05c0dc0486 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 7 Apr 2024 09:44:33 +0200 Subject: fix llvm modules --- src/afl-cc.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index faa46103..45fd398b 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -1369,6 +1369,13 @@ void mode_final_checkout(aflcc_state_t *aflcc, int argc, char **argv) { } + if (getenv("AFL_LLVM_DICT2FILE") && + (getenv("AFL_LLVM_LAF_SPLIT_SWITCHES") || + getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || + getenv("AFL_LLVM_LAF_SPLIT_FLOATS") || + getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) + FATAL("AFL_LLVM_DICT2FILE is incompatible with AFL_LLVM_LAF_*"); + aflcc->cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") || getenv("AFL_GCC_CMPLOG"); -- cgit v1.2.3 From 420a90ff75bc37a2b02055b2587a69741a8194eb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 7 Apr 2024 12:53:41 +0200 Subject: code format --- src/afl-common.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 53524e96..a956fef9 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -64,20 +64,20 @@ u8 last_intr = 0; * FAST on such systems when COARSE is not already defined. * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type. */ -#if defined (OS_DARWIN) || defined (OS_SUNOS) -# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC -#elif defined (OS_FREEBSD) -# define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST +#if defined(OS_DARWIN) || defined(OS_SUNOS) + #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC +#elif defined(OS_FREEBSD) + #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST #endif /* Convert seconds to milliseconds. */ -#define SEC_TO_MS(sec) ((sec)*1000) +#define SEC_TO_MS(sec) ((sec) * 1000) /* Convert seconds to microseconds. */ -#define SEC_TO_US(sec) ((sec)*1000000) +#define SEC_TO_US(sec) ((sec) * 1000000) /* Convert nanoseconds to milliseconds. */ -#define NS_TO_MS(ns) ((ns)/1000000) +#define NS_TO_MS(ns) ((ns) / 1000000) /* Convert nanoseconds to microseconds. */ -#define NS_TO_US(ns) ((ns)/1000) +#define NS_TO_US(ns) ((ns) / 1000) void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { @@ -994,27 +994,35 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) { /* Get unix time in milliseconds */ inline u64 get_cur_time(void) { + struct timespec ts; - int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); if (rc == -1) { - PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", - errno, strerror(errno)); + + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno, + strerror(errno)); + } return SEC_TO_MS((uint64_t)ts.tv_sec) + NS_TO_MS((uint64_t)ts.tv_nsec); + } /* Get unix time in microseconds */ u64 get_cur_time_us(void) { + struct timespec ts; - int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + int rc = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); if (rc == -1) { - PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", - errno, strerror(errno)); + + PFATAL("Failed to obtain timestamp (errno = %i: %s)\n", errno, + strerror(errno)); + } return SEC_TO_US((uint64_t)ts.tv_sec) + NS_TO_US((uint64_t)ts.tv_nsec); + } /* Describe integer. The buf should be -- cgit v1.2.3 From 29544e4d2bf24859030823a4b6a13df00928f7e1 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 7 Apr 2024 18:44:21 +0200 Subject: fix time --- src/afl-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index a956fef9..6d915b00 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -64,7 +64,8 @@ u8 last_intr = 0; * FAST on such systems when COARSE is not already defined. * - macOS has no support of CLOCK_MONOTONIC_COARSE clock type. */ -#if defined(OS_DARWIN) || defined(OS_SUNOS) +#if defined(OS_DARWIN) || defined(OS_SUNOS) || defined(__APPLE__) || \ + defined(__sun) || defined(__NetBSD__) #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC #elif defined(OS_FREEBSD) #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST -- cgit v1.2.3 From 48a862c503483f64db713fd6a0392148b5584ca4 Mon Sep 17 00:00:00 2001 From: Cornelius Aschermann Date: Wed, 13 Mar 2024 11:43:58 -0700 Subject: :Adds stats tracking time spend in calibration/trim/sync This currently does not affect statsd nor the UI. Only the fuzzer_stats file is updated --- src/afl-fuzz-run.c | 26 ++++++++--- src/afl-fuzz-stats.c | 128 +++++++++++++++++++++++++++++---------------------- src/afl-fuzz.c | 1 - 3 files changed, 92 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d764952c..82cdeb81 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -409,6 +409,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, u32 use_tmout = afl->fsrv.exec_tmout; u8 *old_sn = afl->stage_name; + u64 calibration_start_us = get_cur_time_us(); if (unlikely(afl->shm.cmplog_mode)) { q->exec_cksum = 0; } /* Be a bit more generous about timeouts when resuming sessions, or when @@ -504,6 +505,9 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); + // update the time spend in calibration after each execution, as those may be slow + update_calibration_time(afl, &calibration_start_us); + /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed, we want to bail out quickly. */ @@ -650,6 +654,7 @@ abort_calibration: if (!first_run) { show_stats(afl); } + update_calibration_time(afl, &calibration_start_us); return fault; } @@ -669,11 +674,15 @@ void sync_fuzzers(afl_state_t *afl) { afl->stage_max = afl->stage_cur = 0; afl->cur_depth = 0; + u64 sync_start_us = get_cur_time_us(); /* Look at the entries created for every other fuzzer in the sync directory. */ while ((sd_ent = readdir(sd))) { + // since sync can take substantial amounts of time, update time spend every iteration + update_sync_time(afl, &sync_start_us); + u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX]; u32 min_accept = 0, next_min_accept = 0; @@ -861,6 +870,9 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0); + //add time in sync one last time + update_sync_time(afl, &sync_start_us); + afl->last_sync_time = get_cur_time(); afl->last_sync_cycle = afl->queue_cycle; @@ -872,8 +884,9 @@ void sync_fuzzers(afl_state_t *afl) { u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { + u8 needs_write = 0, fault = 0; u32 orig_len = q->len; - + u64 trim_start_us = get_cur_time_us(); /* Custom mutator trimmer */ if (afl->custom_mutators_count) { @@ -897,11 +910,10 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } - if (custom_trimmed) return trimmed_case; + if (custom_trimmed) { fault = trimmed_case; goto abort_trimming; } } - u8 needs_write = 0, fault = 0; u32 trim_exec = 0; u32 remove_len; u32 len_p2; @@ -912,7 +924,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { detected, it will still work to some extent, so we don't check for this. */ - if (unlikely(q->len < 5)) { return 0; } + if (unlikely(q->len < 5)) { fault = 0; goto abort_trimming; } afl->stage_name = afl->stage_name_buf; afl->bytes_trim_in += q->len; @@ -946,6 +958,8 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + update_trim_time(afl, &trim_start_us); + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } /* Note that we don't keep track of crashes or hangs here; maybe TODO? @@ -1039,8 +1053,9 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } abort_trimming: - afl->bytes_trim_out += q->len; + update_trim_time(afl, &trim_start_us); + return fault; } @@ -1104,4 +1119,3 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { return 0; } - diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 4f398863..b39c8299 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -133,6 +133,10 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } +static bool starts_with(char* key, char* line) { + return strncmp(key, line, strlen(key)) == 0; +} + /* load some of the existing stats file when resuming.*/ void load_stats_file(afl_state_t *afl) { @@ -175,65 +179,54 @@ void load_stats_file(afl_state_t *afl) { strcpy(keystring, lstartptr); lptr++; char *nptr; - switch (lineno) { - - case 3: - if (!strcmp(keystring, "run_time ")) - afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); - break; - case 5: - if (!strcmp(keystring, "cycles_done ")) - afl->queue_cycle = - strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; - break; - case 7: - if (!strcmp(keystring, "execs_done ")) - afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); - break; - case 10: - if (!strcmp(keystring, "corpus_count ")) { - - u32 corpus_count = strtoul(lptr, &nptr, 10); - if (corpus_count != afl->queued_items) { - - WARNF( - "queue/ has been modified -- things might not work, you're " - "on your own!"); - - } - - } - - break; - case 12: - if (!strcmp(keystring, "corpus_found ")) - afl->queued_discovered = strtoul(lptr, &nptr, 10); - break; - case 13: - if (!strcmp(keystring, "corpus_imported ")) - afl->queued_imported = strtoul(lptr, &nptr, 10); - break; - case 14: - if (!strcmp(keystring, "max_depth ")) - afl->max_depth = strtoul(lptr, &nptr, 10); - break; - case 21: - if (!strcmp(keystring, "saved_crashes ")) - afl->saved_crashes = strtoull(lptr, &nptr, 10); - break; - case 22: - if (!strcmp(keystring, "saved_hangs ")) - afl->saved_hangs = strtoull(lptr, &nptr, 10); - break; - default: - break; - + if (starts_with("run_time", keystring)){ + afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); + } + if (starts_with("cycles_done", keystring)){ + afl->queue_cycle = + strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; + } + if (starts_with("calibration_time", keystring)){ + afl->calibration_time_us = strtoull(lptr, &nptr, 10) * 1000000; + } + if (starts_with("sync_time", keystring)){ + afl->sync_time_us = strtoull(lptr, &nptr, 10) * 1000000; + } + if (starts_with("trim_time", keystring)){ + afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000; } + if (starts_with("execs_done", keystring)){ + afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); + } + if (starts_with("corpus_count", keystring)) { - } + u32 corpus_count = strtoul(lptr, &nptr, 10); + if (corpus_count != afl->queued_items) { - } + WARNF( + "queue/ has been modified -- things might not work, you're " + "on your own!"); + } + + } + if (starts_with("corpus_found", keystring)){ + afl->queued_discovered = strtoul(lptr, &nptr, 10); + } + if (starts_with("corpus_imported", keystring)){ + afl->queued_imported = strtoul(lptr, &nptr, 10); + } + if (starts_with("max_depth", keystring)) { + afl->max_depth = strtoul(lptr, &nptr, 10); + } + if (starts_with("saved_crashes", keystring)) { + afl->saved_crashes = strtoull(lptr, &nptr, 10); + } + if (starts_with("saved_hangs", keystring)) { + afl->saved_hangs = strtoull(lptr, &nptr, 10); + } + } + } if (afl->saved_crashes) { write_crash_readme(afl); } return; @@ -300,6 +293,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "cycles_done : %llu\n" "cycles_wo_finds : %llu\n" "time_wo_finds : %llu\n" + "fuzz_time : %llu\n" + "calibration_time : %llu\n" + "sync_time : %llu\n" + "trim_time : %llu\n" "execs_done : %llu\n" "execs_per_sec : %0.02f\n" "execs_ps_last_min : %0.02f\n" @@ -345,6 +342,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, : ((afl->start_time == 0 || afl->last_find_time == 0) ? 0 : (cur_time - afl->last_find_time) / 1000), + (runtime - (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / 1000) / 1000, + afl->calibration_time_us / 1000000, + afl->sync_time_us / 1000000, + afl->trim_time_us / 1000000, afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(runtime) / 1000), afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored, afl->queued_discovered, afl->queued_imported, afl->queued_variable, @@ -414,7 +415,6 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, fclose(f); rename(fn_tmp, fn_final); - } #ifdef INTROSPECTION @@ -2438,4 +2438,20 @@ void show_init_stats(afl_state_t *afl) { #undef IB } +void update_calibration_time(afl_state_t *afl, u64* time){ + u64 cur = get_cur_time_us(); + afl->calibration_time_us += cur-*time; + *time = cur; +} + +void update_trim_time(afl_state_t *afl, u64* time){ + u64 cur = get_cur_time_us(); + afl->trim_time_us += cur-*time; + *time = cur; +} +void update_sync_time(afl_state_t *afl, u64* time){ + u64 cur = get_cur_time_us(); + afl->sync_time_us += cur-*time; + *time = cur; +} diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 99491628..102809cd 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -3099,4 +3099,3 @@ stop_fuzzing: } #endif /* !AFL_LIB */ - -- cgit v1.2.3 From 40adc344136c954cdc58e62acb46708816f5870a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Apr 2024 09:24:19 +0200 Subject: fix -V, code format --- src/afl-fuzz-run.c | 25 ++++++++++---- src/afl-fuzz-stats.c | 98 +++++++++++++++++++++++++++++++++++++++------------- src/afl-fuzz.c | 21 ++++++++--- 3 files changed, 108 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 82cdeb81..1c6ce56a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -505,7 +505,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, fault = fuzz_run_target(afl, &afl->fsrv, use_tmout); - // update the time spend in calibration after each execution, as those may be slow + // update the time spend in calibration after each execution, as those may + // be slow update_calibration_time(afl, &calibration_start_us); /* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed, @@ -680,7 +681,8 @@ void sync_fuzzers(afl_state_t *afl) { while ((sd_ent = readdir(sd))) { - // since sync can take substantial amounts of time, update time spend every iteration + // since sync can take substantial amounts of time, update time spend every + // iteration update_sync_time(afl, &sync_start_us); u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX]; @@ -870,7 +872,7 @@ void sync_fuzzers(afl_state_t *afl) { if (afl->foreign_sync_cnt) read_foreign_testcases(afl, 0); - //add time in sync one last time + // add time in sync one last time update_sync_time(afl, &sync_start_us); afl->last_sync_time = get_cur_time(); @@ -910,7 +912,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } - if (custom_trimmed) { fault = trimmed_case; goto abort_trimming; } + if (custom_trimmed) { + + fault = trimmed_case; + goto abort_trimming; + + } } @@ -924,7 +931,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { detected, it will still work to some extent, so we don't check for this. */ - if (unlikely(q->len < 5)) { fault = 0; goto abort_trimming; } + if (unlikely(q->len < 5)) { + + fault = 0; + goto abort_trimming; + + } afl->stage_name = afl->stage_name_buf; afl->bytes_trim_in += q->len; @@ -986,7 +998,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { /* Let's save a clean trace, which will be needed by update_bitmap_score once we're done with the trimming stuff. */ - if (!needs_write) { needs_write = 1; @@ -1001,7 +1012,6 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { } /* Since this can be slow, update the screen every now and then. */ - if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); } ++afl->stage_cur; @@ -1119,3 +1129,4 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { return 0; } + diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index b39c8299..7e1a3b92 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -133,8 +133,10 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { } -static bool starts_with(char* key, char* line) { +static bool starts_with(char *key, char *line) { + return strncmp(key, line, strlen(key)) == 0; + } /* load some of the existing stats file when resuming.*/ @@ -179,25 +181,43 @@ void load_stats_file(afl_state_t *afl) { strcpy(keystring, lstartptr); lptr++; char *nptr; - if (starts_with("run_time", keystring)){ + if (starts_with("run_time", keystring)) { + afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10); + } - if (starts_with("cycles_done", keystring)){ + + if (starts_with("cycles_done", keystring)) { + afl->queue_cycle = strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0; + } - if (starts_with("calibration_time", keystring)){ + + if (starts_with("calibration_time", keystring)) { + afl->calibration_time_us = strtoull(lptr, &nptr, 10) * 1000000; + } - if (starts_with("sync_time", keystring)){ + + if (starts_with("sync_time", keystring)) { + afl->sync_time_us = strtoull(lptr, &nptr, 10) * 1000000; + } - if (starts_with("trim_time", keystring)){ + + if (starts_with("trim_time", keystring)) { + afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000; + } - if (starts_with("execs_done", keystring)){ + + if (starts_with("execs_done", keystring)) { + afl->fsrv.total_execs = strtoull(lptr, &nptr, 10); + } + if (starts_with("corpus_count", keystring)) { u32 corpus_count = strtoul(lptr, &nptr, 10); @@ -206,27 +226,46 @@ void load_stats_file(afl_state_t *afl) { WARNF( "queue/ has been modified -- things might not work, you're " "on your own!"); + sleep(3); } } - if (starts_with("corpus_found", keystring)){ + + if (starts_with("corpus_found", keystring)) { + afl->queued_discovered = strtoul(lptr, &nptr, 10); + } - if (starts_with("corpus_imported", keystring)){ + + if (starts_with("corpus_imported", keystring)) { + afl->queued_imported = strtoul(lptr, &nptr, 10); + } + if (starts_with("max_depth", keystring)) { + afl->max_depth = strtoul(lptr, &nptr, 10); + } + if (starts_with("saved_crashes", keystring)) { + afl->saved_crashes = strtoull(lptr, &nptr, 10); + } + if (starts_with("saved_hangs", keystring)) { + afl->saved_hangs = strtoull(lptr, &nptr, 10); + } + } + } + if (afl->saved_crashes) { write_crash_readme(afl); } return; @@ -334,7 +373,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "\n" "target_mode : %s%s%s%s%s%s%s%s%s%s\n" "command_line : %s\n", - (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000, + (afl->start_time /*- afl->prev_run_time*/) / 1000, cur_time / 1000, runtime / 1000, (u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds, afl->longest_find_time > cur_time - afl->last_find_time @@ -342,11 +381,13 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, : ((afl->start_time == 0 || afl->last_find_time == 0) ? 0 : (cur_time - afl->last_find_time) / 1000), - (runtime - (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / 1000) / 1000, - afl->calibration_time_us / 1000000, - afl->sync_time_us / 1000000, - afl->trim_time_us / 1000000, - afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(runtime) / 1000), + (runtime - + (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / + 1000) / + 1000, + afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000, + afl->trim_time_us / 1000000, afl->fsrv.total_execs, + afl->fsrv.total_execs / ((double)(runtime) / 1000), afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored, afl->queued_discovered, afl->queued_imported, afl->queued_variable, afl->max_depth, afl->current_entry, afl->pending_favored, @@ -415,6 +456,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, fclose(f); rename(fn_tmp, fn_final); + } #ifdef INTROSPECTION @@ -2438,20 +2480,28 @@ void show_init_stats(afl_state_t *afl) { #undef IB } -void update_calibration_time(afl_state_t *afl, u64* time){ - u64 cur = get_cur_time_us(); - afl->calibration_time_us += cur-*time; + +void update_calibration_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->calibration_time_us += cur - *time; *time = cur; + } -void update_trim_time(afl_state_t *afl, u64* time){ - u64 cur = get_cur_time_us(); - afl->trim_time_us += cur-*time; +void update_trim_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->trim_time_us += cur - *time; *time = cur; + } -void update_sync_time(afl_state_t *afl, u64* time){ - u64 cur = get_cur_time_us(); - afl->sync_time_us += cur-*time; +void update_sync_time(afl_state_t *afl, u64 *time) { + + u64 cur = get_cur_time_us(); + afl->sync_time_us += cur - *time; *time = cur; + } + diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 102809cd..00d24ab1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -5,8 +5,9 @@ Originally written by Michal Zalewski Now maintained by Marc Heuse , - Heiko Eißfeldt and - Andrea Fioraldi + Dominik Meier , + Andrea Fioraldi , and + Heiko Eissfeldt Copyright 2016, 2017 Google Inc. All rights reserved. Copyright 2019-2024 AFLplusplus Project. All rights reserved. @@ -199,7 +200,8 @@ static void usage(u8 *argv0, int more_help) { "Test settings:\n" " -s seed - use a fixed seed for the RNG\n" - " -V seconds - fuzz for a specified time then terminate\n" + " -V seconds - fuzz for a specified time then terminate (fuzz time " + "only!)\n" " -E execs - fuzz for an approx. no. of total executions then " "terminate\n" " Note: not precise and can have several more " @@ -2543,8 +2545,6 @@ int main(int argc, char **argv_orig, char **envp) { } // (void)nice(-20); // does not improve the speed - // real start time, we reset, so this works correctly with -V - afl->start_time = get_cur_time(); #ifdef INTROSPECTION u32 prev_saved_crashes = 0, prev_saved_tmouts = 0; @@ -2565,6 +2565,9 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Writing mutation introspection to '%s'", ifn); #endif + // real start time, we reset, so this works correctly with -V + afl->start_time = get_cur_time(); + while (likely(!afl->stop_soon)) { cull_queue(afl); @@ -2585,6 +2588,13 @@ int main(int argc, char **argv_orig, char **envp) { sync_fuzzers(afl); + if (!afl->queue_cycle && afl->afl_env.afl_import_first) { + + // real start time, we reset, so this works correctly with -V + afl->start_time = get_cur_time(); + + } + } ++afl->queue_cycle; @@ -3099,3 +3109,4 @@ stop_fuzzing: } #endif /* !AFL_LIB */ + -- cgit v1.2.3 From 72226d6f89ef47c1e81115eccff887cbf4ec585f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 9 Apr 2024 16:20:42 +0200 Subject: fix shared memory test cases --- src/afl-forkserver.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 6071407a..d8efaa97 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1111,8 +1111,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_NEW_OPT_SHDMEM_FUZZ) && fsrv->add_extra_func && - !ignore_autodict) { + if (status & FS_NEW_OPT_SHDMEM_FUZZ) { if (fsrv->support_shmem_fuzz) { @@ -1129,7 +1128,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if ((status & FS_NEW_OPT_AUTODICT)) { + if (status & FS_NEW_OPT_AUTODICT) { // even if we do not need the dictionary we have to read it -- cgit v1.2.3 From b08df87f5ce2b5cc32d68d7785eab84795370ec2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 11 Apr 2024 09:40:28 +0200 Subject: fix syncing with custom mutator --- src/afl-fuzz-run.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 1c6ce56a..edcddc8e 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -822,7 +822,7 @@ void sync_fuzzers(afl_state_t *afl) { /* See what happens. We rely on save_if_interesting() to catch major errors and save the test case. */ - (void)write_to_testcase(afl, (void **)&mem, st.st_size, 1); + u32 new_len = write_to_testcase(afl, (void **)&mem, st.st_size, 1); fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); @@ -830,7 +830,7 @@ void sync_fuzzers(afl_state_t *afl) { afl->syncing_party = sd_ent->d_name; afl->queued_imported += - save_if_interesting(afl, mem, st.st_size, fault); + save_if_interesting(afl, mem, new_len, fault); afl->syncing_party = 0; munmap(mem, st.st_size); -- cgit v1.2.3