From 3200e6515b9cc988d0d8dccd27257baccc8df021 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 14 Aug 2022 12:24:42 +0200 Subject: add AFL_NO_STARTUP_CALIBRATION feature --- src/afl-fuzz-init.c | 24 ++++++++++++++++++++++++ src/afl-fuzz-queue.c | 10 ++++++++-- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 13 ++++++++++++- 4 files changed, 51 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 4ffcfd2b..32e2b7b8 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -850,6 +850,30 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } +/* In case no initial calibration is to be performed (e.g. huge queue and slow +execution time), then setting AFL_NO_STARTUP_CALIBRATION will help getting +initial data. For this to succeed, non-calibrated corpus entries have to look +especially juicy so they are more likely to be selected then a calibrated good +looking one. */ + +void no_dry_run(afl_state_t *afl) { + + struct queue_entry *q; + u32 idx; + + for (idx = 0; idx < afl->queued_items; idx++) { + + q = afl->queue_buf[idx]; + if (unlikely(!q || q->disabled)) { continue; } + + q->exec_us = 1; + q->bitmap_size = MAP_SIZE; + q->tc_ref = MAP_SIZE; + + } + +} + /* Perform dry run of all test cases to confirm that the app is working as expected. This is done only for the initial inputs, and only once. */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 02d697ab..d8dbdfbe 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -795,8 +795,14 @@ void cull_queue(afl_state_t *afl) { u32 calculate_score(afl_state_t *afl, struct queue_entry *q) { - u32 avg_exec_us = afl->total_cal_us / afl->total_cal_cycles; - u32 avg_bitmap_size = afl->total_bitmap_size / afl->total_bitmap_entries; + u32 cal_cycles = afl->total_cal_cycles; + u32 bitmap_entries = afl->total_bitmap_entries; + + if (unlikely(!cal_cycles)) { cal_cycles = 1; } + if (unlikely(!bitmap_entries)) { bitmap_entries = 1; } + + u32 avg_exec_us = afl->total_cal_us / cal_cycles; + u32 avg_bitmap_size = afl->total_bitmap_size / bitmap_entries; u32 perf_score = 100; /* Adjust score based on execution speed of this path, compared to the diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index ddfd4b31..6770839a 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -265,6 +265,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_cmplog_only_new = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_NO_STARTUP_CALIBRATION", + + afl_environment_variable_len)) { + + afl->afl_env.afl_no_startup_calibration = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_NO_UI", afl_environment_variable_len)) { afl->afl_env.afl_no_ui = diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2e151abb..e3851473 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -273,6 +273,7 @@ static void usage(u8 *argv0, int more_help) { "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" + "AFL_NO_STARTUP_CALIBRATION: no initial seed calibration, start fuzzing at once\n" "AFL_NO_UI: switch status screen off\n" DYN_COLOR @@ -2150,7 +2151,17 @@ int main(int argc, char **argv_orig, char **envp) { memset(afl->virgin_tmout, 255, map_size); memset(afl->virgin_crash, 255, map_size); - perform_dry_run(afl); + if (likely(!afl->afl_env.afl_no_startup_calibration)) { + + perform_dry_run(afl); + + } else { + + ACTF("skipping initial seed calibration due option override"); + usleep(1000); + no_dry_run(afl); + + } if (afl->q_testcase_max_cache_entries) { -- cgit 1.4.1 From 4e980713851c522436b6a6813f27dd95dd4e5fae Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 14 Aug 2022 14:40:26 +0200 Subject: better handling of -fsanitize=..,...,.. lists --- docs/Changelog.md | 2 + src/afl-cc.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index 2ce1d85c..d07cef54 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,8 @@ sending a mail to . - added AFL_NO_STARTUP_CALIBRATION to start fuzzing at once instead of calibrating all initial seeds first. Good for large queues and long execution times, especially in CIs. + - afl-cc: + - better handling of -fsanitize=..,...,.. lists - qemu_mode: - added AFL_QEMU_TRACK_UNSTABLE to log the addresses of unstable edges (together with AFL_DEBUG=1 afl-fuzz). thanks to diff --git a/src/afl-cc.c b/src/afl-cc.c index 6def3ee7..cae6d949 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -51,7 +51,7 @@ static u32 cc_par_cnt = 1; /* Param count, including argv0 */ static u8 clang_mode; /* Invoked as afl-clang*? */ static u8 llvm_fullpath[PATH_MAX]; static u8 instrument_mode, instrument_opt_mode, ngram_size, ctx_k, lto_mode; -static u8 compiler_mode, plusplus_mode, have_instr_env = 0; +static u8 compiler_mode, plusplus_mode, have_instr_env = 0, need_aflpplib = 0; static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0; static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull; static u8 debug; @@ -310,6 +310,69 @@ static u8 *find_object(u8 *obj, u8 *argv0) { } +void parse_fsanitize(char *string) { + + char *p, *ptr = string + strlen("-fsanitize="); + char *new = malloc(strlen(string) + 1); + char *tmp = malloc(strlen(ptr)); + u32 count = 0, len, ende = 0; + strcpy(new, "-fsanitize="); + + do { + + p = strchr(ptr, ','); + if (!p) { + + p = ptr + strlen(ptr) + 1; + ende = 1; + + } + + len = p - ptr; + if (len) { + + strncpy(tmp, ptr, len); + tmp[len] = 0; + // fprintf(stderr, "Found: %s\n", tmp); + ptr += len + 1; + if (*tmp) { + + u32 copy = 1; + if (!strcmp(tmp, "fuzzer")) { + + need_aflpplib = 1; + copy = 0; + + } else if (!strncmp(tmp, "fuzzer", 6)) { + + copy = 0; + + } + + if (copy) { + + if (count) { strcat(new, ","); } + strcat(new, tmp); + ++count; + + } + + } + + } else { + + ptr++; /*fprintf(stderr, "NO!\n"); */ + + } + + } while (!ende); + + strcpy(string, new); + // fprintf(stderr, "string: %s\n", string); + // fprintf(stderr, "new: %s\n", new); + +} + /* Copy argv to cc_params, making the necessary edits. */ static void edit_params(u32 argc, char **argv, char **envp) { @@ -779,20 +842,35 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) || - !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) && - (strncmp(cur, "sanitize-coverage-allow", - strlen("sanitize-coverage-allow")) && - strncmp(cur, "sanitize-coverage-deny", - strlen("sanitize-coverage-deny")) && - instrument_mode != INSTRUMENT_LLVMNATIVE)) { + if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) { + + have_instr_list = 1; + + } + + if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) && + strchr(cur, ',')) { + + parse_fsanitize(cur); + if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; } + + } else if ((!strncmp(cur, "-fsanitize=fuzzer-", + + strlen("-fsanitize=fuzzer-")) || + !strncmp(cur, "-fsanitize-coverage", + strlen("-fsanitize-coverage"))) && + (strncmp(cur, "sanitize-coverage-allow", + strlen("sanitize-coverage-allow")) && + strncmp(cur, "sanitize-coverage-deny", + strlen("sanitize-coverage-deny")) && + instrument_mode != INSTRUMENT_LLVMNATIVE)) { if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); } continue; } - if (!strcmp(cur, "-fsanitize=fuzzer")) { + if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) { u8 *afllib = find_object("libAFLDriver.a", argv[0]); @@ -823,7 +901,15 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - continue; + if (need_aflpplib) { + + need_aflpplib = 0; + + } else { + + continue; + + } } @@ -831,9 +917,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32; if (!strcmp(cur, "-m64")) bit_mode = 64; - if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) - have_instr_list = 1; - if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; -- cgit 1.4.1 From f00d83afbc1b3e82c61ada6b1834eb0f7312e863 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 15 Aug 2022 17:38:53 +0200 Subject: filter pipe in gcc_mode --- src/afl-cc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index cae6d949..4c377ad1 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -822,6 +822,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } + if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; } + if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) { u8 *param = *(argv + 1); -- cgit 1.4.1 From eeab1afd572aacfd60784a09712211d8c0b7fbe5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 17 Aug 2022 12:50:15 +0200 Subject: alt no cal --- src/afl-fuzz-init.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 32e2b7b8..fdd40794 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -858,6 +858,7 @@ looking one. */ void no_dry_run(afl_state_t *afl) { +/* struct queue_entry *q; u32 idx; @@ -871,6 +872,7 @@ void no_dry_run(afl_state_t *afl) { q->tc_ref = MAP_SIZE; } +*/ } -- cgit 1.4.1 From 361263b0f24a2172c4d4be09b1e247aa8d799e9b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 18 Aug 2022 08:06:17 +0200 Subject: better no dry run --- include/afl-fuzz.h | 1 - src/afl-fuzz-init.c | 26 -------------------------- src/afl-fuzz.c | 1 - 3 files changed, 28 deletions(-) (limited to 'src') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 822096e8..23c20cc4 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1123,7 +1123,6 @@ void bind_to_free_cpu(afl_state_t *); void setup_post(afl_state_t *); void read_testcases(afl_state_t *, u8 *); void perform_dry_run(afl_state_t *); -void no_dry_run(afl_state_t *); void pivot_inputs(afl_state_t *); u32 find_start_position(afl_state_t *); void find_timeout(afl_state_t *); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index fdd40794..4ffcfd2b 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -850,32 +850,6 @@ void read_testcases(afl_state_t *afl, u8 *directory) { } -/* In case no initial calibration is to be performed (e.g. huge queue and slow -execution time), then setting AFL_NO_STARTUP_CALIBRATION will help getting -initial data. For this to succeed, non-calibrated corpus entries have to look -especially juicy so they are more likely to be selected then a calibrated good -looking one. */ - -void no_dry_run(afl_state_t *afl) { - -/* - struct queue_entry *q; - u32 idx; - - for (idx = 0; idx < afl->queued_items; idx++) { - - q = afl->queue_buf[idx]; - if (unlikely(!q || q->disabled)) { continue; } - - q->exec_us = 1; - q->bitmap_size = MAP_SIZE; - q->tc_ref = MAP_SIZE; - - } -*/ - -} - /* Perform dry run of all test cases to confirm that the app is working as expected. This is done only for the initial inputs, and only once. */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e3851473..e705f187 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2159,7 +2159,6 @@ int main(int argc, char **argv_orig, char **envp) { ACTF("skipping initial seed calibration due option override"); usleep(1000); - no_dry_run(afl); } -- cgit 1.4.1 From 7b2145b914ba3c8443437c68ae29458d832b1e35 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 19 Aug 2022 09:16:17 +0200 Subject: shorter calibration --- docs/Changelog.md | 2 ++ include/config.h | 5 +++-- src/afl-fuzz-run.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index c5934c4a..e4c59978 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -14,6 +14,8 @@ sending a mail to . - added AFL_NO_STARTUP_CALIBRATION to start fuzzing at once instead of calibrating all initial seeds first. Good for large queues and long execution times, especially in CIs. + - default calibration cycles set to 7 from 8, and only add 5 cycles + to variables queue items instead of 12. - afl-cc: - better handling of -fsanitize=..,...,.. lists - obtain the map size of a target with setting AFL_DUMP_MAP_SIZE=1 diff --git a/include/config.h b/include/config.h index 1689e034..1262668a 100644 --- a/include/config.h +++ b/include/config.h @@ -153,8 +153,9 @@ /* Number of calibration cycles per every new test case (and for test cases that show variable behavior): */ -#define CAL_CYCLES 8U -#define CAL_CYCLES_LONG 20U +#define CAL_CYCLES_FAST 3U +#define CAL_CYCLES 7U +#define CAL_CYCLES_LONG 12U /* Number of subsequent timeouts before abandoning an input file: */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index c0e72ae6..ee4a3298 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -363,7 +363,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, ++q->cal_failed; afl->stage_name = "calibration"; - afl->stage_max = afl->afl_env.afl_cal_fast ? 3 : CAL_CYCLES; + afl->stage_max = afl->afl_env.afl_cal_fast ? CAL_CYCLES_FAST : CAL_CYCLES; /* Make sure the forkserver is up before we do anything, and let's not count its spin-up time toward binary calibration. */ -- cgit 1.4.1 From b4cb3784a5135703444357876c62d19be4a58862 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 19 Aug 2022 13:17:01 +0200 Subject: add malloc check --- src/afl-cc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index 4c377ad1..ffd15476 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -316,6 +316,8 @@ void parse_fsanitize(char *string) { char *new = malloc(strlen(string) + 1); char *tmp = malloc(strlen(ptr)); u32 count = 0, len, ende = 0; + + if (!new || !tmp) { FATAL("could not aquire memory"); } strcpy(new, "-fsanitize="); do { -- cgit 1.4.1 From 4ebde72f28dc38c765c3d4cef396f7c70f05b5e2 Mon Sep 17 00:00:00 2001 From: Eli Kobrin Date: Fri, 19 Aug 2022 13:21:40 +0300 Subject: Change map size dummy value. --- include/types.h | 2 +- src/afl-showmap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/include/types.h b/include/types.h index 4a68b1b0..96ce78f8 100644 --- a/include/types.h +++ b/include/types.h @@ -57,7 +57,7 @@ typedef uint128_t u128; #define FS_OPT_SHDMEM_FUZZ 0x01000000 #define FS_OPT_NEWCMPLOG 0x02000000 #define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000 -// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22 +// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 23 #define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1) #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) #define FS_OPT_SET_MAPSIZE(x) \ diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 4bcd1d59..52d46ac9 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1240,7 +1240,7 @@ int main(int argc, char **argv_orig, char **envp) { u32 save_be_quiet = be_quiet; be_quiet = !debug; - fsrv->map_size = 4194304; // dummy temporary value + fsrv->map_size = FS_OPT_MAX_MAPSIZE; // dummy temporary value u32 new_map_size = afl_fsrv_get_mapsize(fsrv, use_argv, &stop_soon, (get_afl_env("AFL_DEBUG_CHILD") || -- cgit 1.4.1 From 47d5dbbead71bb2da8c025bb49a7b857328f9ee5 Mon Sep 17 00:00:00 2001 From: Eli Kobrin Date: Fri, 19 Aug 2022 14:24:38 +0300 Subject: Fix. --- src/afl-showmap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 52d46ac9..07f30326 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1240,7 +1240,12 @@ int main(int argc, char **argv_orig, char **envp) { u32 save_be_quiet = be_quiet; be_quiet = !debug; - fsrv->map_size = FS_OPT_MAX_MAPSIZE; // dummy temporary value + if (map_size > 4194304) { + fsrv->map_size = map_size; + } + else { + fsrv->map_size = 4194304; // dummy temporary value + } u32 new_map_size = afl_fsrv_get_mapsize(fsrv, use_argv, &stop_soon, (get_afl_env("AFL_DEBUG_CHILD") || -- cgit 1.4.1 From 88ff8aa81e41717abb3d72f8714fdc38591b81a7 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Aug 2022 08:47:30 +0200 Subject: fix gcc_mode cmplog --- docs/Changelog.md | 1 + src/afl-cc.c | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index e4c59978..842b727b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,6 +18,7 @@ sending a mail to . to variables queue items instead of 12. - afl-cc: - better handling of -fsanitize=..,...,.. lists + - fix gcc_mode cmplog - obtain the map size of a target with setting AFL_DUMP_MAP_SIZE=1 note that this will exit the target before main() - qemu_mode: diff --git a/src/afl-cc.c b/src/afl-cc.c index ffd15476..c0449e64 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -498,13 +498,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("-fplugin=%s/afl-gcc-cmptrs-pass.so", obj_path); cc_params[cc_par_cnt++] = fplugin_arg; - } else { - - fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); - cc_params[cc_par_cnt++] = fplugin_arg; - } + fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path); + cc_params[cc_par_cnt++] = fplugin_arg; cc_params[cc_par_cnt++] = "-fno-if-conversion"; cc_params[cc_par_cnt++] = "-fno-if-conversion2"; -- cgit 1.4.1 From eb5a914ef670d43cc41ce130edb4e0586d97e278 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 25 Aug 2022 15:52:46 +0200 Subject: fix pizza mode --- src/afl-fuzz-state.c | 6 +----- src/afl-fuzz.c | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 6770839a..0576f84f 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -604,11 +604,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } - if (afl->afl_env.afl_pizza_mode == 0) { - - afl->afl_env.afl_pizza_mode = 1; - - } else { + if (afl->afl_env.afl_pizza_mode) { afl->pizza_is_served = 1; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index e705f187..1f0fcab1 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2560,7 +2560,7 @@ stop_fuzzing: write_bitmap(afl); save_auto(afl); - if (afl->afl_env.afl_pizza_mode) { + if (afl->pizza_is_served) { SAYF(CURSOR_SHOW cLRD "\n\n+++ Baking aborted %s +++\n" cRST, afl->stop_soon == 2 ? "programmatically" : "by the chef"); -- cgit 1.4.1