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 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 29 deletions(-) (limited to 'src/afl-forkserver.c') 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 } -- cgit 1.4.1 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 --- include/types.h | 7 + src/afl-forkserver.c | 368 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 274 insertions(+), 101 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/include/types.h b/include/types.h index 22332135..d0a2d124 100644 --- a/include/types.h +++ b/include/types.h @@ -49,6 +49,13 @@ typedef uint128_t u128; #define FS_ERROR_OLD_CMPLOG 32 #define FS_ERROR_OLD_CMPLOG_QEMU 64 +/* New Forkserver */ +#define FS_NEW_VERSION_MIN 1 +#define FS_NEW_VERSION_MAX 1 +#define FS_NEW_OPT_MAPSIZE 0x00000001 // parameter: 32 bit value +#define FS_NEW_OPT_SHDMEM_FUZZ 0x00000002 // paramter: none +#define FS_NEW_OPT_AUTODICT 0x00000800 // autodictionary data + /* Reporting options */ #define FS_OPT_ENABLED 0x80000001 #define FS_OPT_MAPSIZE 0x40000000 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 1.4.1 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 --- include/types.h | 7 +- instrumentation/afl-compiler-rt.o.c | 414 ++++++------------------------------ src/afl-forkserver.c | 15 +- 3 files changed, 80 insertions(+), 356 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/include/types.h b/include/types.h index d0a2d124..18c5df91 100644 --- a/include/types.h +++ b/include/types.h @@ -52,9 +52,10 @@ typedef uint128_t u128; /* New Forkserver */ #define FS_NEW_VERSION_MIN 1 #define FS_NEW_VERSION_MAX 1 -#define FS_NEW_OPT_MAPSIZE 0x00000001 // parameter: 32 bit value -#define FS_NEW_OPT_SHDMEM_FUZZ 0x00000002 // paramter: none -#define FS_NEW_OPT_AUTODICT 0x00000800 // autodictionary data +#define FS_NEW_ERROR 0xeffe0000 +#define FS_NEW_OPT_MAPSIZE 0x00000001 // parameter: 32 bit value +#define FS_NEW_OPT_SHDMEM_FUZZ 0x00000002 // parameter: none +#define FS_NEW_OPT_AUTODICT 0x00000800 // autodictionary data /* Reporting options */ #define FS_OPT_ENABLED 0x80000001 diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index caa3c3a8..c342334c 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -264,7 +264,7 @@ static void send_forkserver_error(int error) { u32 status; if (!error || error > 0xffff) return; - status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error)); + status = (FS_NEW_ERROR | error); if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) { return; } } @@ -367,32 +367,13 @@ static void __afl_map_shm(void) { if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) { val = atoi(ptr); } if (val < __afl_final_loc) { - if (__afl_final_loc > FS_OPT_MAX_MAPSIZE) { + if (__afl_final_loc > MAP_INITIAL_SIZE && !getenv("AFL_QUIET")) { - if (!getenv("AFL_QUIET")) - fprintf(stderr, - "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u " - "to be able to run this instrumented program!\n", - __afl_final_loc); - - if (id_str) { - - send_forkserver_error(FS_ERROR_MAP_SIZE); - exit(-1); - - } - - } else { - - if (__afl_final_loc > MAP_INITIAL_SIZE && !getenv("AFL_QUIET")) { - - fprintf(stderr, - "Warning: AFL++ tools might need to set AFL_MAP_SIZE to %u " - "to be able to run this instrumented program if this " - "crashes!\n", - __afl_final_loc); - - } + fprintf(stderr, + "Warning: AFL++ tools might need to set AFL_MAP_SIZE to %u " + "to be able to run this instrumented program if this " + "crashes!\n", + __afl_final_loc); } @@ -400,15 +381,6 @@ static void __afl_map_shm(void) { } - } else { - - if (getenv("AFL_DUMP_MAP_SIZE")) { - - printf("%u\n", MAP_SIZE); - exit(-1); - - } - } if (__afl_sharedmem_fuzzing && (!id_str || !getenv(SHM_FUZZ_ENV_VAR) || @@ -474,14 +446,13 @@ static void __afl_map_shm(void) { if (__afl_debug) { - fprintf( - stderr, - "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " - "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE %u, " - "__afl_final_loc %u, __afl_map_size %u, max_size_forkserver %u/0x%x\n", - id_str == NULL ? "" : id_str, __afl_area_ptr, __afl_area_initial, - __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, - __afl_map_size, FS_OPT_MAX_MAPSIZE, FS_OPT_MAX_MAPSIZE); + fprintf(stderr, + "DEBUG: (1) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " + "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE %u, " + "__afl_final_loc %u, __afl_map_size %u\n", + id_str == NULL ? "" : id_str, __afl_area_ptr, + __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, + __afl_final_loc, __afl_map_size); } @@ -639,12 +610,10 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE " - "%u, __afl_final_loc %u, __afl_map_size %u, " - "max_size_forkserver %u/0x%x\n", + "%u, __afl_final_loc %u, __afl_map_size %u", id_str == NULL ? "" : id_str, __afl_area_ptr, __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, - __afl_final_loc, __afl_map_size, FS_OPT_MAX_MAPSIZE, - FS_OPT_MAX_MAPSIZE); + __afl_final_loc, __afl_map_size); } @@ -855,242 +824,6 @@ void write_error_with_location(char *text, char *filename, int linenumber) { } -#ifdef __linux__ -static void __afl_start_snapshots(void) { - - static u8 tmp[4] = {0, 0, 0, 0}; - u32 status = 0; - u32 already_read_first = 0; - u32 was_killed; - - u8 child_stopped = 0; - - void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); - - /* Phone home and tell the parent that we're OK. If parent isn't there, - assume we're not running in forkserver mode and just execute program. */ - - status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT | FS_OPT_NEWCMPLOG); - if (__afl_sharedmem_fuzzing) { status |= FS_OPT_SHDMEM_FUZZ; } - if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); - if (__afl_dictionary_len && __afl_dictionary) { status |= FS_OPT_AUTODICT; } - memcpy(tmp, &status, 4); - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; } - - if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) { - - if (read(FORKSRV_FD, &was_killed, 4) != 4) { - - write_error("read to afl-fuzz"); - _exit(1); - - } - - if (__afl_debug) { - - fprintf(stderr, "DEBUG: target forkserver recv: %08x\n", was_killed); - - } - - if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) == - (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) { - - __afl_map_shm_fuzz(); - - } - - if ((was_killed & (FS_OPT_ENABLED | FS_OPT_AUTODICT)) == - (FS_OPT_ENABLED | FS_OPT_AUTODICT) && - __afl_dictionary_len && __afl_dictionary) { - - // great lets pass the dictionary through the forkserver FD - u32 len = __afl_dictionary_len, offset = 0; - s32 ret; - - if (write(FORKSRV_FD + 1, &len, 4) != 4) { - - write(2, "Error: could not send dictionary len\n", - strlen("Error: could not send dictionary len\n")); - _exit(1); - - } - - while (len != 0) { - - ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); - - if (ret < 1) { - - write(2, "Error: could not send dictionary\n", - strlen("Error: could not send dictionary\n")); - _exit(1); - - } - - len -= ret; - offset += ret; - - } - - } else { - - // uh this forkserver does not understand extended option passing - // or does not want the dictionary - if (!__afl_fuzz_ptr) already_read_first = 1; - - } - - } - - while (1) { - - int status; - - if (already_read_first) { - - already_read_first = 0; - - } else { - - /* Wait for parent by reading from the pipe. Abort if read fails. */ - if (read(FORKSRV_FD, &was_killed, 4) != 4) { - - write_error("reading from afl-fuzz"); - _exit(1); - - } - - } - - #ifdef _AFL_DOCUMENT_MUTATIONS - if (__afl_fuzz_ptr) { - - static uint32_t counter = 0; - char fn[32]; - sprintf(fn, "%09u:forkserver", counter); - s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION); - if (fd_doc >= 0) { - - if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) { - - fprintf(stderr, "write of mutation file failed: %s\n", fn); - unlink(fn); - - } - - close(fd_doc); - - } - - counter++; - - } - - #endif - - /* If we stopped the child in persistent mode, but there was a race - condition and afl-fuzz already issued SIGKILL, write off the old - process. */ - - if (child_stopped && was_killed) { - - child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) { - - write_error("child_stopped && was_killed"); - _exit(1); // TODO why exit? - - } - - } - - if (!child_stopped) { - - /* Once woken up, create a clone of our process. */ - - child_pid = fork(); - if (child_pid < 0) { - - write_error("fork"); - _exit(1); - - } - - /* In child process: close fds, resume execution. */ - - if (!child_pid) { - - //(void)nice(-20); // does not seem to improve - - signal(SIGCHLD, old_sigchld_handler); - signal(SIGTERM, old_sigterm_handler); - - close(FORKSRV_FD); - close(FORKSRV_FD + 1); - - if (!afl_snapshot_take(AFL_SNAPSHOT_MMAP | AFL_SNAPSHOT_FDS | - AFL_SNAPSHOT_REGS | AFL_SNAPSHOT_EXIT)) { - - raise(SIGSTOP); - - } - - __afl_area_ptr[0] = 1; - memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T)); - - return; - - } - - } else { - - /* Special handling for persistent mode: if the child is alive but - currently stopped, simply restart it with SIGCONT. */ - - kill(child_pid, SIGCONT); - child_stopped = 0; - - } - - /* In parent process: write PID to pipe, then wait for child. */ - - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) { - - write_error("write to afl-fuzz"); - _exit(1); - - } - - if (waitpid(child_pid, &status, WUNTRACED) < 0) { - - write_error("waitpid"); - _exit(1); - - } - - /* In persistent mode, the child stops itself with SIGSTOP to indicate - a successful run. In this case, we want to wake it up without forking - again. */ - - if (WIFSTOPPED(status)) child_stopped = 1; - - /* Relay wait status to pipe, then loop back. */ - - if (write(FORKSRV_FD + 1, &status, 4) != 4) { - - write_error("writing to afl-fuzz"); - _exit(1); - - } - - } - -} - -#endif - /* Fork server logic. */ static void __afl_start_forkserver(void) { @@ -1103,113 +836,92 @@ static void __afl_start_forkserver(void) { old_sigterm_handler = orig_action.sa_handler; signal(SIGTERM, at_exit); -#ifdef __linux__ - if (/*!is_persistent &&*/ !__afl_cmp_map && !getenv("AFL_NO_SNAPSHOT") && - afl_snapshot_init() >= 0) { - - __afl_start_snapshots(); - return; - - } - -#endif - - u8 tmp[4] = {0, 0, 0, 0}; - u32 status_for_fsrv = 0; u32 already_read_first = 0; u32 was_killed; + u32 version = 0x41464c00 + FS_NEW_VERSION_MAX; + u32 tmp = version ^ 0xffffffff, status2, status = version; + u8 *msg = (u8 *)&status; + u8 *reply = (u8 *)&status2; u8 child_stopped = 0; void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); - if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) { - - status_for_fsrv |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); + /* Phone home and tell the parent that we're OK. If parent isn't there, + assume we're not running in forkserver mode and just execute program. */ - } + // return because possible non-forkserver usage + if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; } - if (__afl_dictionary_len && __afl_dictionary) { + if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); } + if (tmp != status2) { - status_for_fsrv |= FS_OPT_AUTODICT; + write_error("wrong forkserver message from AFL++ tool"); + _exit(1); } - if (__afl_sharedmem_fuzzing) { status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; } - if (status_for_fsrv) { + // send the set/requested options to forkserver + status = FS_NEW_OPT_MAPSIZE; // we always send the map size + if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; } + if (__afl_dictionary_len && __afl_dictionary) { - status_for_fsrv |= (FS_OPT_ENABLED | FS_OPT_NEWCMPLOG); + status |= FS_NEW_OPT_AUTODICT; } - memcpy(tmp, &status_for_fsrv, 4); + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - /* Phone home and tell the parent that we're OK. If parent isn't there, - assume we're not running in forkserver mode and just execute program. */ - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; } - - __afl_connected = 1; + // Now send the parameters for the set options, increasing by option number - if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) { + // FS_NEW_OPT_MAPSIZE - we always send the map size + status = __afl_map_size; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1); + // FS_NEW_OPT_SHDMEM_FUZZ - no data - if (__afl_debug) { - - fprintf(stderr, "DEBUG: target forkserver recv: %08x\n", was_killed); + // FS_NEW_OPT_AUTODICT - send autodictionary + if (__afl_dictionary_len && __afl_dictionary) { - } + // pass the dictionary through the forkserver FD + u32 len = __afl_dictionary_len, offset = 0; - if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) == - (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) { + if (write(FORKSRV_FD + 1, &len, 4) != 4) { - __afl_map_shm_fuzz(); + write(2, "Error: could not send dictionary len\n", + strlen("Error: could not send dictionary len\n")); + _exit(1); } - if ((was_killed & (FS_OPT_ENABLED | FS_OPT_AUTODICT)) == - (FS_OPT_ENABLED | FS_OPT_AUTODICT) && - __afl_dictionary_len && __afl_dictionary) { + while (len != 0) { - // great lets pass the dictionary through the forkserver FD - u32 len = __afl_dictionary_len, offset = 0; + s32 ret; + ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); - if (write(FORKSRV_FD + 1, &len, 4) != 4) { + if (ret < 1) { - write(2, "Error: could not send dictionary len\n", - strlen("Error: could not send dictionary len\n")); + write_error("could not send dictionary"); _exit(1); } - while (len != 0) { - - s32 ret; - ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); - - if (ret < 1) { - - write(2, "Error: could not send dictionary\n", - strlen("Error: could not send dictionary\n")); - _exit(1); - - } + len -= ret; + offset += ret; - len -= ret; - offset += ret; + } - } + } - } else { + // send welcome message as final message + status = version; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // uh this forkserver does not understand extended option passing - // or does not want the dictionary - if (!__afl_fuzz_ptr) already_read_first = 1; + // END forkserver handshake - } + __afl_connected = 1; - } + if (__afl_sharedmem_fuzzing) { __afl_map_shm_fuzz(); } while (1) { @@ -1225,7 +937,7 @@ static void __afl_start_forkserver(void) { if (read(FORKSRV_FD, &was_killed, 4) != 4) { - // write_error("read from afl-fuzz"); + write_error("read from AFL++ tool"); _exit(1); } 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 1.4.1 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 --- include/cmplog.h | 19 ++++----- instrumentation/afl-compiler-rt.o.c | 78 +++++++++++++++++++++++++++---------- src/afl-forkserver.c | 10 +++++ src/afl-fuzz-redqueen.c | 10 ++--- src/afl-fuzz.c | 6 ++- test/test-llvm.sh | 2 +- 6 files changed, 87 insertions(+), 38 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/include/cmplog.h b/include/cmplog.h index 6bfc146b..91c2a665 100644 --- a/include/cmplog.h +++ b/include/cmplog.h @@ -43,13 +43,11 @@ struct cmp_header { - unsigned hits : 24; - unsigned id : 24; - unsigned shape : 5; - unsigned type : 2; - unsigned attribute : 4; - unsigned overflow : 1; - unsigned reserved : 4; + unsigned hits : 6; // up to 63 entries, we have CMP_MAP_H = 32 + unsigned shape : 6; // 63 bytes, we support 32 max + unsigned type : 2; // 4, we use 3: none, rtn, cmp + unsigned attribute : 4; // 16 for arithmetic comparison types + unsigned reserved : 6; } __attribute__((packed)); @@ -59,14 +57,17 @@ struct cmp_operands { u64 v1; u64 v0_128; u64 v1_128; + u64 unused; + u8 unused1; + u8 unused2; } __attribute__((packed)); struct cmpfn_operands { - u8 v0[31]; + u8 v0[32]; u8 v0_len; - u8 v1[31]; + u8 v1[32]; u8 v1_len; } __attribute__((packed)); diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c342334c..a154bcf7 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -186,6 +186,8 @@ __thread u32 __afl_prev_ctx; struct cmp_map *__afl_cmp_map; struct cmp_map *__afl_cmp_map_backup; +static u8 __afl_cmplog_max_len = 16; + /* Child pid? */ static s32 child_pid; @@ -730,6 +732,12 @@ static void __afl_map_shm(void) { #endif // __AFL_CODE_COVERAGE + if (!__afl_cmp_map && getenv("AFL_CMPLOG_DEBUG")) { + + __afl_cmp_map_backup = __afl_cmp_map = malloc(sizeof(struct cmp_map)); + + } + } /* unmap SHM. */ @@ -1893,7 +1901,8 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) { void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) { - if (unlikely(!__afl_cmp_map || arg1 == arg2)) return; + if (likely(!__afl_cmp_map)) return; + if (unlikely(arg1 == arg2)) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -1931,7 +1940,8 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) { // fprintf(stderr, "hook4 arg0=%x arg1=%x attr=%u\n", arg1, arg2, attr); - if (unlikely(!__afl_cmp_map || arg1 == arg2)) return; + if (likely(!__afl_cmp_map)) return; + if (unlikely(arg1 == arg2)) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -1969,7 +1979,8 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) { // fprintf(stderr, "hook8 arg0=%lx arg1=%lx attr=%u\n", arg1, arg2, attr); - if (unlikely(!__afl_cmp_map || arg1 == arg2)) return; + if (likely(!__afl_cmp_map)) return; + if (unlikely(arg1 == arg2)) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -2012,7 +2023,8 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr, // (u64)(arg1 >> 64), (u64)arg1, (u64)(arg2 >> 64), (u64)arg2, size + 1, // attr); - if (unlikely(!__afl_cmp_map || arg1 == arg2)) return; + if (likely(!__afl_cmp_map)) return; + if (unlikely(arg1 == arg2 || size > __afl_cmplog_max_len)) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -2056,6 +2068,7 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr, void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) { if (likely(!__afl_cmp_map)) return; + if (16 > __afl_cmplog_max_len) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -2249,13 +2262,25 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) { // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len); if (likely(!__afl_cmp_map)) return; - if (unlikely(!len)) return; - int len0 = MIN(len, 31); + if (unlikely(!len || len > __afl_cmplog_max_len)) return; + + int len0 = MIN(len, 32); + int len1 = strnlen(ptr1, len0); - if (len1 < 31) len1 = area_is_valid(ptr1, len1 + 1); + if (len1 <= 32) len1 = area_is_valid(ptr1, len1 + 1); + if (len1 > __afl_cmplog_max_len) len1 = 0; + int len2 = strnlen(ptr2, len0); - if (len2 < 31) len2 = area_is_valid(ptr2, len2 + 1); - int l = MAX(len1, len2); + if (len2 <= 32) len2 = area_is_valid(ptr2, len2 + 1); + if (len2 > __afl_cmplog_max_len) len2 = 0; + + int l; + if (!len1) + l = len2; + else if (!len2) + l = len1; + else + l = MAX(len1, len2); if (l < 2) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); @@ -2299,10 +2324,18 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) { // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2); if (likely(!__afl_cmp_map)) return; if (unlikely(!ptr1 || !ptr2)) return; - int len1 = strnlen(ptr1, 30) + 1; - int len2 = strnlen(ptr2, 30) + 1; - int l = MAX(len1, len2); - if (l < 3) return; + int len1 = strnlen(ptr1, 31) + 1; + int len2 = strnlen(ptr2, 31) + 1; + if (len1 > __afl_cmplog_max_len) len1 = 0; + if (len2 > __afl_cmplog_max_len) len2 = 0; + int l; + if (!len1) + l = len2; + else if (!len2) + l = len1; + else + l = MAX(len1, len2); + if (l < 2) return; uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); @@ -2344,7 +2377,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { /* u32 i; - if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return; + if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return; fprintf(stderr, "rtn arg0="); for (i = 0; i < 32; i++) fprintf(stderr, "%02x", ptr1[i]); @@ -2357,10 +2390,10 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2); if (likely(!__afl_cmp_map)) return; int l1, l2; - if ((l1 = area_is_valid(ptr1, 31)) <= 0 || - (l2 = area_is_valid(ptr2, 31)) <= 0) + if ((l1 = area_is_valid(ptr1, 32)) <= 0 || + (l2 = area_is_valid(ptr2, 32)) <= 0) return; - int len = MIN(31, MIN(l1, l2)); + int len = MIN(__afl_cmplog_max_len, MIN(l1, l2)); // fprintf(stderr, "RTN2 %u\n", len); uintptr_t k = (uintptr_t)__builtin_return_address(0); @@ -2409,7 +2442,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) { #if 0 /* u32 i; - if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return; + if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return; fprintf(stderr, "rtn_n len=%u arg0=", len); for (i = 0; i < len; i++) fprintf(stderr, "%02x", ptr1[i]); @@ -2421,12 +2454,15 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) { // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len); if (likely(!__afl_cmp_map)) return; - if (unlikely(!len)) return; - int l = MIN(31, len); + if (!len) return; + int l = MIN(32, len), l1, l2; - if ((l = area_is_valid(ptr1, l)) <= 0 || (l = area_is_valid(ptr2, l)) <= 0) + if ((l1 = area_is_valid(ptr1, l)) <= 0 || (l2 = area_is_valid(ptr2, l)) <= 0) return; + len = MIN(l1, l2); + if (len > __afl_cmplog_max_len) return; + // fprintf(stderr, "RTN2 %u\n", l); uintptr_t k = (uintptr_t)__builtin_return_address(0); k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1)); 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 */ diff --git a/test/test-llvm.sh b/test/test-llvm.sh index 53bbd7b4..aef7a5e2 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -62,7 +62,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { $ECHO "$RED[!] llvm_mode threadsafe instrumentation failed" CODE=1 } - rm -f test-instr.ts.0 test-instr.ts.1 + rm -f test-instr.ts.0 test-instr.ts.1 test-instr.ts } || { $ECHO "$RED[!] llvm_mode (threadsafe) failed" CODE=1 -- cgit 1.4.1 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 --- include/afl-fuzz.h | 2 +- include/config.h | 10 +- include/persistent_replay.h | 152 +++++++++++++++++++--------- instrumentation/README.persistent_mode.md | 30 +++++- instrumentation/afl-compiler-rt.o.c | 58 ++++++----- src/afl-forkserver.c | 5 +- utils/persistent_mode/persistent_demo_new.c | 6 +- 7 files changed, 182 insertions(+), 81 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 864bc6b6..f95dcc20 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -125,7 +125,7 @@ #endif /* ^!SIMPLE_FILES */ #ifdef AFL_PERSISTENT_RECORD - #define RECORD_PREFIX "RECORD:" + #define RECORD_PREFIX "RECORD:" #endif #define STAGE_BUF_SIZE (64) /* usable size for stage name buf in afl_state */ diff --git a/include/config.h b/include/config.h index 1649f110..d44cda9c 100644 --- a/include/config.h +++ b/include/config.h @@ -83,10 +83,14 @@ will be kept and written to the crash/ directory as RECORD:... files. Note that every crash will be written, not only unique ones! */ -// #define AFL_PERSISTENT_RECORD +#define AFL_PERSISTENT_RECORD -/* Builds compiler-rt with support to replay persistent records */ -// #define AFL_PERSISTENT_REPLAY +/* Adds support in compiler-rt to replay persistent records */ +#define AFL_PERSISTENT_REPLAY + +/* Adds support in compiler-rt to replay persistent records in @@-style + * harnesses */ +// #define AFL_PERSISTENT_REPLAY_ARGPARSE /* console output colors: There are three ways to configure its behavior * 1. default: colored outputs fixed on: defined USE_COLOR && defined diff --git a/include/persistent_replay.h b/include/persistent_replay.h index b1a55e9f..58b22fb4 100644 --- a/include/persistent_replay.h +++ b/include/persistent_replay.h @@ -11,71 +11,116 @@ #include static unsigned short int is_replay_record; -static unsigned int replay_record; -static unsigned int replay_record_cnt; -static char replay_record_path[PATH_MAX]; -static char **record_arg; -static char *replay_record_dir; -static struct dirent **record_list; +static unsigned int replay_record; +static unsigned int replay_record_cnt; +static char replay_record_path[PATH_MAX]; +static char *replay_record_dir; +static struct dirent **record_list; + +#ifdef AFL_PERSISTENT_REPLAY_ARGPARSE +static char **record_arg = NULL; +#endif // AFL_PERSISTENT_REPLAY_ARGPARSE static int select_files(const struct dirent *dirbuf) { char fn[4096]; - if (dirbuf->d_name[0] == '.'){ + if (dirbuf->d_name[0] == '.') { + return 0; + } else { + snprintf(fn, sizeof(fn), "RECORD:%06u", replay_record); return !!strstr(dirbuf->d_name, fn); + } + } - + static int compare_files(const struct dirent **da, const struct dirent **db) { - - unsigned int c1=0, c2=0; + + unsigned int c1 = 0, c2 = 0; sscanf((*da)->d_name, "RECORD:%*u,cnt:%06u", &c1); sscanf((*db)->d_name, "RECORD:%*u,cnt:%06u", &c2); - return c1-c2; + return c1 - c2; + } -__attribute__((destructor)) static void __afl_record_replay_destroy(void){ - for (int i=0; i < replay_record_cnt; i++) { +__attribute__((destructor)) static void __afl_record_replay_destroy(void) { + + for (int i = 0; i < replay_record_cnt; i++) { + free(record_list[i]); + } + free(record_list); + } -__attribute__((constructor)) static void __afl_record_replay_init(int argc, char **argv) { - +__attribute__((constructor)) static void __afl_record_replay_init( +#ifdef AFL_PERSISTENT_REPLAY_ARGPARSE + int argc, char **argv +#endif // AFL_PERSISTENT_REPLAY_ARGPARSE +) { + +#ifdef AFL_PERSISTENT_REPLAY_ARGPARSE char **argp; +#endif // AFL_PERSISTENT_REPLAY_ARGPARSE + + struct stat sb; + + /* caveat: if harness uses @@ and we don't pass it, it will regardless loop + * the number of iterations defined for AFL_LOOP (on the same file)*/ + if (!(is_replay_record = !!getenv("AFL_PERSISTENT_REPLAY"))) { - /* caveat: if harness uses @@ and we don't pass it, it will regardless loop the number of iterations defined for AFL_LOOP (on the same file)*/ - if(!(is_replay_record = !!getenv("AFL_PERSISTENT_REPLAY"))){ // printf("[warning] AFL_PERSISTENT_REPLAY not set.\n"); return; + } replay_record = atoi(getenv("AFL_PERSISTENT_REPLAY")); replay_record_dir = getenv("AFL_PERSISTENT_DIR"); - replay_record_cnt = scandir(replay_record_dir ? replay_record_dir : "./", &record_list, select_files, compare_files); - if (!replay_record_cnt){ - printf("[error] Can't find the requested record!\n"); + if (!(stat(replay_record_dir, &sb) == 0 && S_ISDIR(sb.st_mode))) { + + fprintf(stderr, "[error] Can't find the requested record directory!\n"); is_replay_record = 0; + return; + } + replay_record_cnt = scandir(replay_record_dir ? replay_record_dir : "./", + &record_list, select_files, compare_files); + + if (!replay_record_cnt) { + + fprintf(stderr, "[error] Can't find the requested record!\n"); + is_replay_record = 0; + + } + +#ifdef AFL_PERSISTENT_REPLAY_ARGPARSE argp = argv; - while (*argp){ - if (!strcmp(*argp, "@@")){ + while (*argp) { + + if (!strcmp(*argp, "@@")) { + record_arg = argp; *record_arg = replay_record_path; break; + } + ++argp; + } +#endif // AFL_PERSISTENT_REPLAY_ARGPARSE + } /* only used if explictly included for compatibility @@ -83,67 +128,80 @@ __attribute__((constructor)) static void __afl_record_replay_init(int argc, char #ifdef AFL_COMPAT -#ifndef PATH_MAX - #define PATH_MAX 4096 -#endif + #ifndef PATH_MAX + #define PATH_MAX 4096 + #endif -#define FUZZ_BUF_SIZE 1024000 + #define FUZZ_BUF_SIZE 1024000 -// extern ssize_t read(int fildes, void *buf, size_t nbyte); + // extern ssize_t read(int fildes, void *buf, size_t nbyte); -//extern int __afl_persistent_loop(unsigned int max_cnt); -//extern unsigned char fuzz_buf[]; + // extern int __afl_persistent_loop(unsigned int max_cnt); + // extern unsigned char fuzz_buf[]; -#ifndef __AFL_HAVE_MANUAL_CONTROL - #define __AFL_HAVE_MANUAL_CONTROL -#endif + #ifndef __AFL_HAVE_MANUAL_CONTROL + #define __AFL_HAVE_MANUAL_CONTROL + #endif -#define __AFL_FUZZ_TESTCASE_LEN (read(0, fuzz_buf, FUZZ_BUF_SIZE)) -#define __AFL_FUZZ_TESTCASE_BUF fuzz_buf -#define __AFL_FUZZ_INIT() void sync(void); -#define __AFL_INIT() sync() -#define __AFL_LOOP(x) __afl_persistent_loop(x) + #define __AFL_FUZZ_TESTCASE_LEN (read(0, fuzz_buf, FUZZ_BUF_SIZE)) + #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf + #define __AFL_FUZZ_INIT() void sync(void); + #define __AFL_INIT() sync() + #define __AFL_LOOP(x) __afl_persistent_loop(x) unsigned char fuzz_buf[FUZZ_BUF_SIZE]; int __afl_persistent_loop(unsigned int max_cnt) { - static unsigned int cycle_cnt = 1; + static unsigned int cycle_cnt = 1; static unsigned short int inited = 0; - char tcase[PATH_MAX]; + char tcase[PATH_MAX]; + + if (is_replay_record) { - if( is_replay_record ){ + if (!inited) { - if (!inited){ cycle_cnt = replay_record_cnt; inited = 1; + } snprintf(tcase, PATH_MAX, "%s/%s", - replay_record_dir ? replay_record_dir : "./", - record_list[replay_record_cnt-cycle_cnt]->d_name); - + replay_record_dir ? replay_record_dir : "./", + record_list[replay_record_cnt - cycle_cnt]->d_name); + #ifdef AFL_PERSISTENT_REPLAY_ARGPARSE if (record_arg) { + *record_arg = tcase; - } else { + + } else + + #endif // AFL_PERSISTENT_REPLAY_ARGPARSE + { + int fd = open(tcase, O_RDONLY); dup2(fd, 0); close(fd); + } } else { - if (!inited){ + if (!inited) { + cycle_cnt = max_cnt; inited = 1; + } } return cycle_cnt--; + } #endif // AFL_COMPAT -#endif // _HAVE_PERSISTENT_REPLAY_H \ No newline at end of file +#endif // _HAVE_PERSISTENT_REPLAY_H + diff --git a/instrumentation/README.persistent_mode.md b/instrumentation/README.persistent_mode.md index 14e59f4a..b5d982b0 100644 --- a/instrumentation/README.persistent_mode.md +++ b/instrumentation/README.persistent_mode.md @@ -195,4 +195,32 @@ Then as first line after the `__AFL_LOOP` while loop: int len = __AFL_FUZZ_TESTCASE_LEN; ``` -And that is all! \ No newline at end of file +And that is all! + +## 6) Persistent record, and replay + +If your software under test requires keeping a state between persistent loop iterations (i.e., a stateful network stack), you can use the `AFL_PERSISTENT_RECORD` variable as described in the [environment variables documentation](../docs/env_variables.md). + +To easily replay a crashing, or hanging record, you can use the persistent replay functionality by compiling AFL++ after uncommenting the `AFL_PERSISTENT_REPLAY` define in [config.h](../include/config.h). + +You can then run the test binary specifying the record number via the AFL_PERSISTENT_REPLAY environment variable (i.e., `RECORD:XXXXX`` -> `AFL_PERSISTENT_REPLAY=XXXXX`). +The directory where the record files live can be specified via the `AFL_PERSISTENT_DIR` environment varilable, otherwise by default it will be considered the current directory (`./`). + +If your harness reads the input files from arguments using the special `@@` argument you will need to define `AFL_PERSISTENT_ARGPARSE` in `config.h`, or before including the `persistent_replay.h` header file as show before. +In order to offer transparent support to harnesses using the `@@` command line argument, arguments are parsed by the `__afl_record_replay_init` init function. Since not all systems support passing arguments to initializers, this functionality is disabled by default, it's recommendable to use the `__AFL_FUZZ_TESTCASE_BUF/__AFL_FUZZ_TESTCASE_LEN` shared memory mechanism instead. + +### 7) Drop in replay functionality + +To use the replay functionality without having to use `afl-cc` you can just define `AFL_COMPAT` and include the [include/persistent_replay.h](../include/persistent_replay.h) self contained header file that provides a drop-in replacement for the persistent loop mechanism. + +```c +#ifndef __AFL_FUZZ_TESTCASE_LEN + #define AFL_COMPAT + // #define AFL_PERSISTENT_REPLAY_ARGPARSE + #include "persistent_replay.h" +#endif + +__AFL_FUZZ_INIT(); +``` + +A simple example is provided in [persistent_demo_new.c](../utils/persistent_mode/persistent_demo_new.c). \ No newline at end of file diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 0fa22aee..037caaf0 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -84,7 +84,7 @@ #include #ifdef AFL_PERSISTENT_REPLAY -#include "persistent_replay.h" + #include "persistent_replay.h" #endif /* Globals needed by the injected instrumentation. The __afl_area_initial region @@ -1344,37 +1344,49 @@ int __afl_persistent_loop(unsigned int max_cnt) { #ifdef AFL_PERSISTENT_REPLAY -#ifndef PATH_MAX - #define PATH_MAX 4096 -#endif + #ifndef PATH_MAX + #define PATH_MAX 4096 + #endif - static u8 inited = 0; - char tcase[PATH_MAX]; + static u8 inited = 0; + char tcase[PATH_MAX]; - if( unlikely(is_replay_record) ){ + if (unlikely(is_replay_record)) { - if (!inited){ - cycle_cnt = replay_record_cnt; - inited = 1; - } + if (!inited) { - snprintf(tcase, PATH_MAX, "%s/%s", - replay_record_dir ? replay_record_dir : "./", - record_list[replay_record_cnt-cycle_cnt]->d_name); + cycle_cnt = replay_record_cnt; + inited = 1; + + } + + snprintf(tcase, PATH_MAX, "%s/%s", + replay_record_dir ? replay_record_dir : "./", + record_list[replay_record_cnt - cycle_cnt]->d_name); + + #ifdef AFL_PERSISTENT_REPLAY_ARGPARSE + if (record_arg) { + + *record_arg = tcase; + + } else + + #endif // AFL_PERSISTENT_REPLAY_ARGPARSE + { + + int fd = open(tcase, O_RDONLY); + dup2(fd, 0); + close(fd); + + } - if (record_arg) { - *record_arg = tcase; - } else { - int fd = open(tcase, O_RDONLY); - dup2(fd, 0); - close(fd); - } return cycle_cnt--; + } else -#endif +#endif - if (first_pass) { + if (first_pass) { /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. On subsequent calls, the parent will take care of that, but on the first 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]; diff --git a/utils/persistent_mode/persistent_demo_new.c b/utils/persistent_mode/persistent_demo_new.c index 40ada9e1..3d9d90a6 100644 --- a/utils/persistent_mode/persistent_demo_new.c +++ b/utils/persistent_mode/persistent_demo_new.c @@ -31,8 +31,8 @@ /* this lets the source compile without afl-clang-fast/lto */ #ifndef __AFL_FUZZ_TESTCASE_LEN -#define AFL_COMPAT -#include "persistent_replay.h" + #define AFL_COMPAT + #include "persistent_replay.h" #endif __AFL_FUZZ_INIT(); @@ -86,8 +86,6 @@ int main(int argc, char **argv) { if (buf[5] == '!') { printf("six\n"); - char *nullo = NULL+1; - *nullo = 'p'; abort(); } -- cgit 1.4.1 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/afl-forkserver.c') 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 1.4.1 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/afl-forkserver.c') 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 1.4.1 From f2b7357ff3efedca53a7cd856469b439c2e547ef Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Feb 2024 13:09:16 +0100 Subject: fixes --- instrumentation/SanitizerCoverageLTO.so.cc | 15 ++++++++------- src/afl-forkserver.c | 14 +++++++++++--- unicorn_mode/build_unicorn_support.sh | 4 ++-- 3 files changed, 21 insertions(+), 12 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index f55aeca2..43c6ca40 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1673,12 +1673,12 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( inst = inst_save; - } + /* if (debug) + fprintf(stderr, "Next instrumentation (%u-%u=%u %u-%u=%u)\n", inst, + inst_save, inst - inst_save, afl_global_id, save_global, + afl_global_id - save_global);*/ - /* if (debug) - fprintf(stderr, "Next instrumentation (%u-%u=%u %u-%u=%u)\n", inst, - inst_save, inst - inst_save, afl_global_id, save_global, - afl_global_id - save_global);*/ + } for (auto &BB : F) { @@ -1932,8 +1932,9 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( } - // if (shouldInstrumentBlock(F, &BB, DT, PDT, Options)) - // BlocksToInstrument.push_back(&BB); + if (!instrument_ctx) + if (shouldInstrumentBlock(F, &BB, DT, PDT, Options)) + BlocksToInstrument.push_back(&BB); /* for (auto &Inst : BB) { 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."); } diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index baca2171..be7ee7f0 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -201,7 +201,7 @@ echo "[*] Installing Unicorn python bindings..." cd unicorn/bindings/python || exit 1 if [ -z "$VIRTUAL_ENV" ]; then echo "[*] Info: Installing python unicornafl using --user" - THREADS=$CORES $PYTHONBIN -m pip install --user --force .|| exit 1 + THREADS=$CORES $PYTHONBIN -m pip install --user --break-system-packages --force .|| exit 1 else echo "[*] Info: Installing python unicornafl to virtualenv: $VIRTUAL_ENV" THREADS=$CORES $PYTHONBIN -m pip install --force .|| exit 1 @@ -211,7 +211,7 @@ echo "[*] Installing Unicornafl python bindings..." cd bindings/python || exit 1 if [ -z "$VIRTUAL_ENV" ]; then echo "[*] Info: Installing python unicornafl using --user" - THREADS=$CORES $PYTHONBIN -m pip install --user --force .|| exit 1 + THREADS=$CORES $PYTHONBIN -m pip install --user --break-system-packages --force .|| exit 1 else echo "[*] Info: Installing python unicornafl to virtualenv: $VIRTUAL_ENV" THREADS=$CORES $PYTHONBIN -m pip install --force .|| exit 1 -- cgit 1.4.1 From 07bc202e0ad940e0cc7c8770f69ceb32ed851384 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 9 Feb 2024 13:51:05 +0100 Subject: fixes --- qemu_mode/QEMUAFL_VERSION | 2 +- qemu_mode/qemuafl | 2 +- src/afl-forkserver.c | 2 +- test/test-qemu-mode.sh | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION index b4e764b7..6f2a5979 100644 --- a/qemu_mode/QEMUAFL_VERSION +++ b/qemu_mode/QEMUAFL_VERSION @@ -1 +1 @@ -e63c9af193 +40033af00c diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index e63c9af1..40033af0 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit e63c9af1937c13163cd1bc8bc276101441cbe70a +Subproject commit 40033af00c4c5de172ed4fe60c21b9edbd2c189d 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"); } diff --git a/test/test-qemu-mode.sh b/test/test-qemu-mode.sh index 8eb7cb67..2ba81d02 100755 --- a/test/test-qemu-mode.sh +++ b/test/test-qemu-mode.sh @@ -63,7 +63,7 @@ test -e ../afl-qemu-trace && { { export AFL_PRELOAD=../libcompcov.so export AFL_COMPCOV_LEVEL=2 - ../afl-fuzz -m ${MEM_LIMIT} -V07 -Q -i in -o out -- ./test-compcov >>errors 2>&1 + AFL_NO_UI=1 ../afl-fuzz -V07 -Q -i in -o out -- ./test-compcov 2>&1 unset AFL_PRELOAD unset AFL_COMPCOV_LEVEL } >>errors 2>&1 @@ -88,7 +88,7 @@ test -e ../afl-qemu-trace && { test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "aarch64" -o ! "${SYS%%arm*}" && { $ECHO "$GREY[*] running afl-fuzz for qemu_mode cmplog, this will take approx 10 seconds" { - ../afl-fuzz -m none -V07 -Q -c 0 -l 3 -i in -o out -- ./test-compcov >>errors 2>&1 + ../afl-fuzz -V07 -Q -c 0 -l 3 -i in -o out -- ./test-compcov >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/default/queue/id:000001* 2>/dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode cmplog" -- cgit 1.4.1 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/afl-forkserver.c') 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 1.4.1 From 01f442d81016188e847eae5320882cb1fbfa6dc8 Mon Sep 17 00:00:00 2001 From: Leon Weiß 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/afl-forkserver.c') 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 1.4.1 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/afl-forkserver.c') 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 1.4.1 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/afl-forkserver.c') 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 1.4.1 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/afl-forkserver.c') 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 1.4.1 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 --- include/envs.h | 40 ++++++++++++++++++++-------------------- src/afl-forkserver.c | 2 ++ 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'src/afl-forkserver.c') diff --git a/include/envs.h b/include/envs.h index d32e2f92..56a4916c 100644 --- a/include/envs.h +++ b/include/envs.h @@ -95,26 +95,26 @@ static char *afl_environment_variables[] = { "AFL_MAX_DET_EXTRAS", "AFL_NO_X86", // not really an env but we dont want to warn on it "AFL_NOOPT", "AFL_NYX_AUX_SIZE", "AFL_NYX_DISABLE_SNAPSHOT_MODE", - "AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT", "AFL_PASSTHROUGH", "AFL_PATH", - "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD", - "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV", - "AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN", "AFL_QEMU_COMPCOV", - "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", - "AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL", "AFL_QEMU_PERSISTENT_ADDR", - "AFL_QEMU_PERSISTENT_CNT", "AFL_QEMU_PERSISTENT_GPR", - "AFL_QEMU_PERSISTENT_HOOK", "AFL_QEMU_PERSISTENT_MEM", - "AFL_QEMU_PERSISTENT_RET", "AFL_QEMU_PERSISTENT_RETADDR_OFFSET", - "AFL_QEMU_PERSISTENT_EXITS", "AFL_QEMU_INST_RANGES", - "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", "AFL_QEMU_TRACK_UNSTABLE", - "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", "AFL_REAL_PATH", - "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", "AFL_SKIP_CPUFREQ", - "AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD", "AFL_STATSD_HOST", - "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", "AFL_SYNC_TIME", - "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", "AFL_TMIN_EXACT", - "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", "AFL_USE_ASAN", - "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN", - "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", - "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN", + "AFL_NYX_HANDLE_INVALID_WRITE", "AFL_NYX_LOG", "AFL_NYX_REUSE_SNAPSHOT", + "AFL_PASSTHROUGH", "AFL_PATH", "AFL_PERFORMANCE_FILE", + "AFL_PERSISTENT_RECORD", "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", + "AFL_TARGET_ENV", "AFL_PYTHON_MODULE", "AFL_QEMU_CUSTOM_BIN", + "AFL_QEMU_COMPCOV", "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", + "AFL_QEMU_DISABLE_CACHE", "AFL_QEMU_DRIVER_NO_HOOK", "AFL_QEMU_FORCE_DFL", + "AFL_QEMU_PERSISTENT_ADDR", "AFL_QEMU_PERSISTENT_CNT", + "AFL_QEMU_PERSISTENT_GPR", "AFL_QEMU_PERSISTENT_HOOK", + "AFL_QEMU_PERSISTENT_MEM", "AFL_QEMU_PERSISTENT_RET", + "AFL_QEMU_PERSISTENT_RETADDR_OFFSET", "AFL_QEMU_PERSISTENT_EXITS", + "AFL_QEMU_INST_RANGES", "AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_SNAPSHOT", + "AFL_QEMU_TRACK_UNSTABLE", "AFL_QUIET", "AFL_RANDOM_ALLOC_CANARY", + "AFL_REAL_PATH", "AFL_SHUFFLE_QUEUE", "AFL_SKIP_BIN_CHECK", + "AFL_SKIP_CPUFREQ", "AFL_SKIP_CRASHES", "AFL_SKIP_OSSFUZZ", "AFL_STATSD", + "AFL_STATSD_HOST", "AFL_STATSD_PORT", "AFL_STATSD_TAGS_FLAVOR", + "AFL_SYNC_TIME", "AFL_TESTCACHE_SIZE", "AFL_TESTCACHE_ENTRIES", + "AFL_TMIN_EXACT", "AFL_TMPDIR", "AFL_TOKEN_FILE", "AFL_TRACE_PC", + "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", + "AFL_USE_TSAN", "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", + "AFL_NO_SNAPSHOT", "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN", "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", NULL }; 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 1.4.1 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/afl-forkserver.c') 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 1.4.1 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/afl-forkserver.c') 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 1.4.1